C++多线程中用临界区控制全局变量的访问冲突问题
困扰了我很长时间的多线程访问全局变量今天终于解决了,所以得记录一下。。控制全局变量的方法很多,有信号量、临界区等。。这里我记录一个用临界区控制访问冲突的例子。非常好用。
#include <windows.h> #include <iostream> using namespace std; //首先做两个线程,实现两个线程间的同步 上次是利用互斥对象实现线程间的同步CreateMutex函数和事件对象间的同步CreateEvent函数,这次用关键代码段(临界区对象)来实现 DWORD WINAPI Fun1Proc(LPVOID lpParameter); DWORD WINAPI Fun2Proc(LPVOID lpParameter); int tickets=100; CRITICAL_SECTION g_cs; //1.定义一个临界区对象 void main() { HANDLE hThread1; HANDLE hThread2; hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL); hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL); CloseHandle(hThread1); CloseHandle(hThread2); InitializeCriticalSection(&g_cs); //2.初始化临界对象 Sleep(4000); DeleteCriticalSection(&g_cs); //3.当函数要结束的时候释放所有没有被拥有的临界区对象相关的成员 } DWORD WINAPI Fun1Proc(LPVOID lpParameter) { while(TRUE) { EnterCriticalSection(&g_cs); //4.判断是否有线程在访问公共资源,如果有线程正在访问就,不能执行下面的 if(tickets>0) { Sleep(1); cout<<"Thread1 sell tickets:"<<tickets--<<endl; } else break; LeaveCriticalSection(&g_cs); //5.执行完代码段的就离开临界区,那么下个线程就可以访问资源了,这就好像我们要用公用电话(共有资源),我们必须先看看电话厅里是否有人,有人就不能此时用,没人就可以用这个资源了 } //7.注意一定要释放,否则线程2就没有执行的机会 “谁拥有谁释放” return 0; } DWORD WINAPI Fun2Proc(LPVOID lpParameter) { while(TRUE) { EnterCriticalSection(&g_cs); if(tickets>0) { Sleep(1); cout<<"Thread2 sell tickets:"<<tickets--<<endl; } else break; LeaveCriticalSection(&g_cs); //8.我们可以将线程2注释起来看看,运行发现,线程1卖出第100张后不再卖了,其余的都是线程2卖的 } return 0; //6.程序这样执行,同步建立了。没有出现重复和0的票号 }