[操作系统]Windows环境下的多线程临界资源访问

目录

WaitForSingleObject

CreateMutex

CreateThread 

TerminateThread 

                    SetEvent/ResetEvent 

                    ReleaseMutex


DWORD WaitForSingleObject( HANDLE THandle, DWORD Timeout)

作用:使线程处于等待状态,如等待某一事件的触发。用最简单的语言说就是这个对象有两个状态比如我们称0和1,称什么一点也不重要,有信号和无信号就是相对的两个状态,没什么意义,你就认为一个状态是0另一个状态是1。
在程序里如果加了WaitForSingleObject,那么程序到这里就去检测你给他的那个句柄的状态,如果是0程序就停在这里了,如果是1,程序就继续下去。
那么线程同步就要利用这两个状态。假如你有两个线程,都有可能访问同一个文件,而同一个文件是不能被两个线程同时写入的,那么你就需要在写入之前先判断文件有没有被另一个线程在写入,如果有则等着,等另一个线程写完之后你再继续,我们不能用一个死循坏来尝试打开文件知道成功为止,这样会让CPU有非常高的占用率。
这里你就要创建一个对象,这个对象有两个状态,我们约定,如果一个线程要写入文件之前就把这个对象状态变成0,写完之后把它变回1,那么另一个线程在写文件之前只要检测这个对象是不是为0就可以确定文件有没有被另一个线程在写入了。检测的过程就用WaitForSingleObject来操作,如果为1,WaitForSingleObject就和没这句话一样立刻执行下去了,如果那个对象是个0,那么WaitForSingleObject就会停在这里等,等到另一个线程写完文件,因为那个线程在写完文件之后会把对象变成1。
这个状态1我们命名为有信号状态,状态0我们称无信号状态。我们就把这个对象叫做互斥体,他起到了对这个文件读写的互斥作用。这整个写文件之前之后改变互斥体状态,写之前检测互斥体状态这个过程就是一个线程的同步。
同步是编程的人自己要考虑的问题,系统不会帮你同步,也就是说我们进行了上述的约定之后,你在编程的时候必须要在写入文件之前将互斥体置为无信号状态,写完之后置为有信号状态

THandle:等待触发的句柄

Timeout:等待多长时间,单位ms。想无限等待下去,Timeout参数可以指定系统常量INFINITE。

返回值:WAIT_ABANDONED:指定的对象是一个互斥对象,该对象没有被拥有该对象的线程在线程结束前释放。互斥对象的所                                                          有权被同意授予调用该函数的线程。互斥对象被设置成为无信号状态。当THandle为mutex时,如                                                           果拥有mutex的线程在结束时没有释放核心对象会引发此返回值。

                                                          表示对象有信号,但还是不能执行 ,一般是因为未获取到锁或其他原因

          WAIT_OBJECT_0:核心对象已被激活,对线程来说,表示执行结束

          WAIT_TIMEOUT:等待超时,表示等待指定时间内,对象一直没有信号,即线程没执行完

          WAIT_FAILED:出现错误,可通过GetLastError得到错误代码


HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName )

LPSECURITY_ATTRIBUTES lpMutexAttributes: 指向安全属性的指针

BOOL bInitialOwner:初始化互斥对象的所有者 。

                                      如果为TRUE,调用互斥对象的线程获得互斥对象的所有权  如果为FALSE,则不拥有

                                     true:人工重置事件对象,等待该事件的所有进程都将进入运行
                                     false:自动重置事件对象,等待该事件中的一个进程可变为调度。表示刚刚创建的这个Mutex                                                                   不属于任何线程,也就是没有任何线程拥有他,一个Mutex在没有任何线程拥有他的时                                                                             候,他是处于激发态的, 所以处于有信号状态。
LPCTSTR lpName :指向互斥对象名的指针。

                                      如果lpName跟一个已存在的事件、信号、文件映射对象匹配,即命名的互斥对象已存在,

                                     则CreateMutex函数失败,
                                     true: 创建该事件对象后,触发事件

                                     false:不触发事件。


HANDLE CreateThread(LPSECURITY_ATTRIBUTES secAttr, SIZE_T  stackSize,LPTHREAD_START_ROUTINE  threadFunc,    
LPVOID    param,DWORD  flags,   LPDWORD  threadID)

secAttr:描述线程内核对象安全属性的指针,设置为NULL,就会使用默认的安全描述符。

stackSize:表示线程栈空间大小。如果为0(1MB),那么这个线程堆栈的大小与创建它的线程相同。

threadFunc:表示新线程所执行的线程函数地址,多个线程可以使用同一个函数地址,线程的执行一直持续到线程函数返回。

param:传给线程函数的参数。

flags:标志了线程的执行状态,为0表示线程创建之后立即就可以进行调度,如果为CREATE_SUSPENDED,
            线程则以挂起状态创建并等待执行,这样它就无法调度,直到调用ResumeThread()。

threadID:将以的长整型返回线程的ID号,传入NULL表示不需要返回该线程ID号。


BOOL  TerminateThread(HANDLE   hThread, DWORD   dwExitCode)

hThread :欲令其结束线程的handle,该线程就是我们的行动目标。

dwExitCode: 该线程的结束代码。


SetEvent/ResetEvent(EVENT)

EVENT有两种状态:发信号,不发信号。

SetEvent/ResetEvent分别将EVENT置为这两种状态分别是发信号与不发信号。 


BOOL WINAPI  ReleaseMutex(HANDLE hMutex)

作用:释放互斥对象的控制权。一个线程释放了互斥对象的控制权后,如果其他进程在等待互斥对象置位,则等待的线程可以得到该互斥对象,等待函数返回,互斥对象被新的线程所拥有。
返回值:TRUE表示成功,FALSE表示失败。
hMutex:HANDLE,制定一个互斥体的句柄。
 

你可能感兴趣的:([操作系统]Windows环境下的多线程临界资源访问)