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

关键代码段

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

相关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;
//线程函数1
DWORD 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;
}
//线程函数2
DWORD 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;
}

运行结果

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

这里写图片描述

原文地址:https://www.cnblogs.com/jinxiang1224/p/8468290.html