多线程的同步方式

一、原子互锁家族函数:

  (1)InterlockedIncrement:  加1操作。

  (2)InterlockedDecrement: 减1操作。

  (3)InterlockedExchangeAdd: 加上“指定”的值,可以加上一个负数。

  (4)InterlockedExchange、InterlockedExchangePointer: 能够以原子操作的方式用第二个的值来代替第一个参数的值。

  特点:一般情况下,在多线程编程中如果对某一个变量的值进行改变的话,使用以上互锁函数确实比较方便,但有时候多线程操作更为复杂的东西,比如对于给结构体赋值、对链表插入或者删除等等,以上互锁函数不能满足。

二、Critical Sections(关键代码段、关键区域、临界区域)

  (1)初始化:InitializeCriticalSection(&csObj);     

  (2)删除:DeleteCriticalSection(&csObj);

  (3)进入:EnterCriticalSection(&csObj);

  (4)尝试进入:TryEnterCriticalSection(&csObj);

  (5)离开:LeaveCriticalSection(&csObj);

  特点:(1)是一个用户模式的对象,不是系统核心对象,所以执行速度快有效率。

     (2)因为不是核心对象,所以不能跨进程使用。

     (3)可以多次“进入”,但必须多次“推出”。

     (4)最好不要同时进入或等待Critical Sections,容易造成死锁。

     (5)无法检测到进入到Critical Sections里面的线程当前是否已经退出。

三、Mutex(互斥器)

  (1)创建互斥器:HANDLE ghMutex = CreateMutex(NULL, FALSE, FALSE);

  (2)打开一个已经存在的互斥器:OpenMutex;

  (3)获取互斥器的拥有权: DWORD dwWaitResult = WaitForSingleObject(ghMutex, INFINITE);

  (4)释放互斥器的拥有权:ReleaseMutex(ghMutex);

  (5)关闭互斥器:CloseHandle(ghMutex);

  

DWORD dwWaitResult = WaitForSingleObject(ghMutex, INFINITE);
        switch (dwWaitResult)
        {
        case WAIT_ABANDONED:
        case WAIT_OBJECT_0:
            num++;
            ReleaseMutex(ghMutex);
        default:
            break;
        }

  注意:Mutex可以跨进程使用,所以器名称对整个系统而言是全局的,所以不要命名不要过于普通。

特点:

  (1)是一个系统核心对象,所以又安全描述指针,用完了要CloseHandle关闭句柄,这些是内核对象的共同特征:

  (2)因为是核心对象,所以执行速度会比Critical Sections慢几乎100倍的时间。

  (3)因为是核心对象,可以跨进程使用。

  (4)Mutex使用正确的情况下不会发生死锁。

  (5)在“等待”一个Mutex的时候,可以指定“结束等待”的时间长度。

  (6)可以检测到当前拥有互斥器所有权的线程是否已经退出,Wait...函数返回:WAIT_ABANDONED。

四、Semaphores(信号量)

  (1)创建一个信号量:hgSemaphore = CreateSemaphore(NULL, 10, 10, NULL);

  (2)获取互斥器的拥有权:DWORD dwWaitResult = WaitForSingleObject(hgSemaphore, 0);

  (3)释放互斥器的拥有权:ReleaseSemaphore(hgSemaphore,1,NULL);

  (4)关闭互斥器:CloseHandle(hgSemaphore);;

while (true)
    {
        DWORD dwWaitResult = WaitForSingleObject(hgSemaphore, 0);
        switch (dwWaitResult)
        {
        case WAIT_OBJECT_0:
            CString csText;
            csText.Format(_T("ThreadId:%d
"), GetCurrentThreadId());
            OutputDebugString(csText);
            ReleaseSemaphore(hgSemaphore,1,NULL);
        case WAIT_TIMEOUT:
            CString csText;
            csText.Format(_T("wait time out!
"), GetCurrentThreadId());
            OutputDebugString(csText);
        }
    }

 特点:

  (1)是一个系统核心对象,所以又安全描述指针,用完了要CloseHandle关闭句柄,这些是内核对象的共同特征:

  (2)因为是核心对象,所以执行速度会比较慢。

  (3)因为是核心对象,可以跨进程使用。

  (4)Semaphores使用正确的情况下不会发生死锁。

  (5)在“等待”一个Semaphores的时候,可以指定“结束等待”的时间长度。

  (6)非排他性的占有,跟Critical Sections和Mutex不同,这两种而言是排他性占有,即:同一时间只能又单一线程操作对象,而Semaphores同一时间内可以有多个线程获得目标并操作。

五、Event Objects(事件)

111
原文地址:https://www.cnblogs.com/zwj-199306231519/p/14725286.html