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


    关键代码段

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

    相关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;
    }

    运行结果

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

    这里写图片描述

  • 相关阅读:
    PyCharm小技巧
    How to install torcs package in Debian
    QT4.8.6静态编译
    Debian初识(选择最佳镜像发布站点加入source.list文件)
    Dev-C++ 小问题锦集
    ubuntu 12.04lts 安装mysql ,并通过QT连接
    win7下安装ubuntu14.04lts 双系统
    cmake打印变量值
    驾车常识:小轿车灯光
    汽车点火开关的功能介绍
  • 原文地址:https://www.cnblogs.com/jinxiang1224/p/8468289.html
Copyright © 2020-2023  润新知