利用关键代码段实现线程同步

来源:互联网 发布:唐国强诸葛亮知乎 编辑:程序博客网 时间:2024/05/21 17:01

关键代码段

关键代码段,也叫做临界区,它是指包含共享资源的一小段代码,这段代码被执行前需要得到访问权才能被执行,否则会一直等到;

相关API

  • 初始化关键代码段对象
void WINAPI InitializeCriticalSection(  __out  LPCRITICAL_SECTION lpCriticalSection);
  • 等待关键代码段对象的所有权
void WINAPI EnterCriticalSection(  __inout  LPCRITICAL_SECTION lpCriticalSection);
  • 释放关键代码段对象的所有权
void WINAPI LeaveCriticalSection(  __inout  LPCRITICAL_SECTION lpCriticalSection);
  • 释放为关键代码段分配的所有资源
void WINAPI DeleteCriticalSection(  __inout  LPCRITICAL_SECTION lpCriticalSection);
  • 使用规则:

    先定义一个 CRITICAL_SECTION 的全局对象,然后用InitializeCriticalSection初始化该对象;在线程函数中的关键代码段前使用EnterCriticalSection函数获得所有权,离开关键代码后使用LeaveCriticalSection函数释放所有权;在程序的最后需要利用DeleteCriticalSection为关键代码段对象释放所有的系统资源;

具体代码

#include "stdafx.h"#include <iostream>#include <afxmt.h>using namespace std;int g_nIndex = 0;const int nMaxCnt = 20;CRITICAL_SECTION g_csLock;//线程函数1DWORD WINAPI Thread1SynByCS(LPVOID lpParameter){    while (TRUE)    {        //等待直到获得指定对象的所有权        EnterCriticalSection(&g_csLock);        //关键代码段-begin        if (g_nIndex++ < nMaxCnt)        {            cout << "Index = "<< g_nIndex << " ";            cout << "Thread2 is runing" << endl;            //权限释放            LeaveCriticalSection(&g_csLock);        }        else        {            //权限释放            LeaveCriticalSection(&g_csLock);            //关键代码段-end            break;        }    }    return 0;}//线程函数2DWORD WINAPI Thread2SynByCS(LPVOID lpParameter){    while (TRUE)    {        //等待直到获得指定对象的所有权        EnterCriticalSection(&g_csLock);         //关键代码段-begin        if (g_nIndex++ < nMaxCnt)        {            cout << "Index = "<< g_nIndex << " ";            cout << "Thread2 is runing" << endl;            //权限释放            LeaveCriticalSection(&g_csLock);        }        else        {            //权限释放            LeaveCriticalSection(&g_csLock);            //关键代码段-end            break;        }     }    return 0;}int _tmain(int argc, _TCHAR* argv[]){    HANDLE hThread1 = NULL;    HANDLE hThread2 = NULL;    //初始化关键代码段对象    InitializeCriticalSection(&g_csLock);    //创建新的线程    hThread1 = CreateThread(NULL,0,Thread1SynByCS,NULL,0,NULL);//立即执行    hThread2 = CreateThread(NULL,0,Thread2SynByCS,NULL,0,NULL);//立即执行    //无须对新线程设置优先级等操作,关闭之    //良好的编码习惯    CloseHandle(hThread1);    CloseHandle(hThread2);    Sleep(3000);    //释放为关键代码段对象分配的所有资源    DeleteCriticalSection(&g_csLock);    return 0;}

运行结果

从运行结果可以看出,程序执行是按照预期的流程进行,没有异常现象

这里写图片描述

0 0
原创粉丝点击