Windows C++ 四种线程同步的创建与使用方式

 

1.互斥量

   /*
    *用于保护全局变量、硬件端口、管道识别码、窗口客户区
    *多个线程共享资源时,优先考虑互斥量
    *Mutex 可以跨进程使用,所以其名称对整个系统而言是全局的
    *param1:安全特征,可以指定,也可以不填
    *param2:线程所有权,设置为TRUE,调用方立即获得互斥量所有权
    *param3:互斥量名称必须指定
    */

此处若把参数2设置为TRUE,即创建线程互斥量,当前线程即获取该互斥量,需在同一个线程释放

h_Mutex = CreateMutex(NULL, FALSE, "mutex");

    /*
    *为现有的已经存在的互斥量对象创建一个新句柄
    *param1:请求访问方式 安全特征
    *        MUTEX_ALL_ACCESS    请求对互斥体的完全访问
    *        MUTEX_MODIFY_STATE    允许使用 ReleaseMutex 函数
    *        SYNCHRONIZE            允许互斥体对象同步使用
    *
    *param2:如希望子进程能够继承句柄,则为TRUE
    *param3:要打开对象的名字
    *互斥量不存在返回失败ERROR_FILE_NOT_FOUND 必须释放互斥量ReleaseMutex
    */

HANDLE ret = OpenMutex(MUTEX_ALL_ACCESS, TRUE, "mutex");

等待互斥量

WaitForSingleObject(h_Mutex, INFINITE);//等待互斥量

释放互斥量

BOOL ret = ReleaseMutex(h_Mutex);

2.信号量

    /*
    *用于保护全局变量、硬件端口、管道识别码、窗口客户区
    *多个线程共享资源时,优先考虑互斥量
    *Semaphores 可以跨进程使用,所以其名称对整个系统而言是全局的
    *param1:安全特征,可以指定,也可以不填 NULL默认安全方式
    *        MUTEX_ALL_ACCESS    请求对互斥体的完全访问
    *        MUTEX_MODIFY_STATE    允许使用 ReleaseMutex 函数
    *        SYNCHRONIZE            允许互斥体对象同步使用
    *param2:初始数目以确定信号量初始触发状态,设置为0,为未触发状态,如果当前资源计数等于0,那么信号量处于未触发状态;那么系统会让调用线程进入等待状态
    *param3:可同时持有信号量所有权的最多线程对象数目
    *param4:必须提供信号量名
    */

创建信号量

h_Semaphore = CreateSemaphore(NULL, 0, 1, "semaphore");

等待信号量

WaitForSingleObject(h_Semaphore, INFINITE);//等待互斥量

释放信号量

BOOL ret = ReleaseSemaphore(h_Semaphore, 1, NULL);

 

3.事件对象

    /*
    *param1:安全特征,可以指定,也可以不填 NULL默认安全方式.确定返回的句柄是否可被子进程继承,是NULL,此句柄不能被继承
    *param2:用于确定事件对象,TRUE代表必须把ResetEvent中事件对象设置为未触发状态.(TRUE)必须使用ResetEvent()手动重置为无信号状态
    *                      FALSE当一个等待线程被释放时,自动重置状态为无信号状态
    *param3:设置事件初始状态,为TRUE则表示立即设置为触发状态
    *param4:必须提供事件名
    */

创建事件对象

h_Event = CreateEvent(NULL, TRUE,TRUE,"event");

将事件对象设置为已触发状态

BOOL ret = SetEvent(h_Event);

将事件对象设置为未触发状态

BOOL ret = ResetEvent(h_Event);

脉冲事件,将事件对象设置为已触发状态,然后将其重置为未触发状态,释放特定数量的等待线程

BOOL ret = PulseEvent(h_Event);

事件对象在创建时候的四种情况分析,针对参数二和参数三

1.人工重置事件:使用手动重置为无信号状态,初始化时有信号状态,调用WaitForSingleObject不会等待

CreateEvent(NULL, TRUE, TRUE, NULL)

2.人工重置事件:使用手动重置为无信号状态,初始化时为无信号状态 调用WaitForSingleObject会一直等待

CreateEvent(NULL, TRUE, FALSE, NULL);

若某个线程调用WaitForSingleObject(hEvent,INFINITE) 则会一直等待,需要先调用SetEvent()设置为有信号状态,才能继续执行,否则一直在等待;ResetEvent(),要想有信号需调用SetEvent(hEvent)

3.自动重置事件:当一个等待线程被释放时,自动重置为无信号状态,初始是有信号状态,调用WaitForSingleObject不会等待

CreateEvent(NULL, FALSE, TRUE, NULL);

另一个线程若还需要等到通知,即在当前线程调用SetEvent()

4.自动重置事件:线程释放后自动重置为无信号状态,初始化时为无信号状态

CreateEvent(NULL, FALSE, FALSE, NULL);

 

4.临界区

   临界区的功能与互斥量相同,同一时刻只被一个线程拥有
   运行速度更快,开销更小
   开始临界区对象处于未触发状态,被释放后处于触发状态

    临界区创建以及使用方式。
    1.先声明临界区对象
    2.初始化
    3.让线程进入临界区
    4.任务完成后,让线程离开临界区
    5.释放资源

    //1
    CRITICAL_SECTION c_section;
    //2
    InitializeCriticalSection(&c_section);
    //3
    EnterCriticalSection(&c_section); //或者    TryEnterCriticalSection(&c_section);
    //4
    LeaveCriticalSection(&c_section);
    //5
    DeleteCriticalSection(&c_section);

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章