本文共 1900 字,大约阅读时间需要 6 分钟。
临界区又称关键代码段,指的是一小段代码在代码执行前,它需要独占一些资源,只能在单独的进程中使用。程序中通常将多线程同时访问的某个资源的程序片段称为临界区。需要定义一个CRITICAL_SECTION类型的变量,然后调用InitializeCriticalSection函数对变量进行初始化。相对于互斥量来说,系统分配临界区对象的速度更快,所需的开销更小。
定义一个全局的锁 CRITICAL_SECTION的实例和一个静态全局变量
CRITICAL_SECTIONcs;// 临界区的声明 static intn_AddValue = 0;//定义一个静态的全部变量n_AddValue
创建两个线程函数,代码实现如下
//第一个线程 UINT FirstThread(LPVOIDlParam) { EnterCriticalSection(&cs);//进入临界区,对需要保护的资源进行操作 for(int i =0; i<10;i++){ n_AddValue ++; cout <<"n_AddValue in FirstThread is"<<< endl; } LeaveCriticalSection(&cs);//离开临界区 return 0; } //第二个线程 UINT SecondThread(LPVOIDlParam) { EnterCriticalSection(&cs);//进入临界区 for(int i =0; i<10;i++){ n_AddValue ++; cout <<"n_AddValue in SecondThread is"< << endl; } LeaveCriticalSection(&cs);//离开临界区 return 0; }
在主函数添加以下代码
CWinThread *pFirstThread, *pSecondThread;//存储函数AfxBeginThread返回的CWinThread指针 InitializeCriticalSection(&cs);//初始化临界区 pFirstThread = AfxBeginThread(test->FirstThread, LPVOID(NULL));//启动第一个线程 pSecondThread = AfxBeginThread(test->SecondThread, LPVOID(NULL));//启动第二个线程 HANDLE hThreadHandle[2];// hThreadHandle[0] = pFirstThread->m_hThread; hThreadHandle[1] = pSecondThread->m_hThread; //等待线程返回 WaitForMultipleObjects(2, hThreadHandle, TRUE, INFINITE);
很多人对CRITICAL_SECTION的理解是错误的,认为CRITICAL_SECTION是锁定了资源,其实,CRITICAL_SECTION是不能够“锁定”资源的,它能够完成的功能,是同步不同线程的代码段。简单说,当一个线程执行了EnterCritialSection之后,cs里面的信息便被修改了,以指明哪一个线程占用了它。而此时,并没有任何资源被“锁定”。不管什么资源,其它线程都还是可以访问的(当然,执行的结果可能是错误的)。只不过,在这个线程尚未执行LeaveCriticalSection之前,其它线程碰到EnterCritialSection语句的话,就会处于等待状态,相当于线程被挂起了。 这种情况下,就起到了保护共享资源的作用。
使用CriticalSection只适合在CriticalSection区域内处理的事情是非常简单的,耗时非常短的(程序级别的时间),如果处理事务用的时间比较长的话,就不适合用CriticalSection这种方式来解决问题
参考:
转载地址:http://vkiii.baihongyu.com/