C++多线程之使用Mutex和Critical_Section

来源:互联网 发布:btspread新域名 编辑:程序博客网 时间:2024/06/08 03:52

Mutex和Critical Section都是主要用于限制多线程(Multithread)对全局或共享的变量、对象或内存空间的访问。下面是其主要的异同点(不同的地方用绿色表示)。

这里写图片描述

下面是一些补充:

l 请先检查你的设计,把不必要的全局或共享对象改为局部对象。全局的东西越少,出问题的可能就越小。

l 每次你使用EnterCriticalSection时,请不要忘了在函数的所有可能返回的地方都加上LeaveCriticalSection。对于Mutex也同样。若你把这个问题和Win32 structured exception或C++ exception一起考虑,你会发现问题并不是那么简单。自定义一个封装类可能是一种解决方案,以Critical Section为例的代码如下所示:

class csholder{    CRITICAL_SECTION *cs;public:    csholder(CRITICAL_SECTION *c): cs(c)    { EnterCriticalSection(cs); }    ~csholder() { LeaveCriticalSection(cs); }};CRITICAL_SECTION some_cs;void foo(){    // ...    csholder hold_some(&some_cs);    // ... CS protected code here    // at return or if an exception happens    // hold_some's destructor is automatically called}

l 根据你的互斥范围需求的不同,把Mutex或Critical Section定义为类的成员变量,或者静态类变量。

l 若你想限制访问的全局变量只有一个而且类型比较简单(比如是LONG或PVOID型),你也可以使用InterlockedXXX系列函数来保证一个线程写多个线程读。

Demo程序

#include <Windows.h>#include <iostream>using namespace std;int index = 0;// 临界区结构对象CRITICAL_SECTION g_cs;HANDLE hMutex = NULL;void changeMe(){ cout << index++ << endl;}void changeMe2(){ cout << index++ << endl;}void changeMe3(){ cout << index++ << endl;}DWORD WINAPI th1(LPVOID lpParameter){ while(1) {  Sleep(1600); //sleep 1.6 s  // 进入临界区  EnterCriticalSection(&g_cs);  // 等待互斥对象通知  //WaitForSingleObject(hMutex, INFINITE);  // 对共享资源进行写入操作  //cout << "a" << index++ << endl;  changeMe();  changeMe2();  changeMe3();  // 释放互斥对象  //ReleaseMutex(hMutex);  // 离开临界区  LeaveCriticalSection(&g_cs);   } return 0;}DWORD WINAPI th2(LPVOID lpParameter){ while(1) {  Sleep(2000); //sleep 2 s  // 进入临界区  EnterCriticalSection(&g_cs);  // 等待互斥对象通知  //WaitForSingleObject(hMutex, INFINITE);  //cout << "b" << index++ << endl;  changeMe();  changeMe2();  changeMe3();  // 释放互斥对象  //ReleaseMutex(hMutex);  // 离开临界区  LeaveCriticalSection(&g_cs);  } return 0;}int main(int argc, char* argv[]){ // 创建互斥对象 //hMutex = CreateMutex(NULL, TRUE, NULL); // 初始化临界区 InitializeCriticalSection(&g_cs); HANDLE hThread1; HANDLE hThread2; hThread1 = CreateThread(NULL, 0, th1,  NULL, 0, NULL); hThread2 = CreateThread(NULL, 0, th2,  NULL, 0, NULL); int k;  cin >> k;  printf("Hello World!\n"); return 0;}
0 0
原创粉丝点击