zoukankan      html  css  js  c++  java
  • 线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的用法

    转自:http://www.itcodeworld.com/?p=105

    使用结构CRITICAL_SECTION 需加入头文件#include “afxmt.h”

    定义一个全局的锁 CRITICAL_SECTION的实例
    和一个静态全局变量

    CRITICAL_SECTION cs;//可以理解为锁定一个资源
    static int n_AddValue = 0;//定义一个静态的全部变量n_AddValue

    创建两个线程函数,代码实现如下:

    代码
    //第一个线程
    UINT FirstThread(LPVOID lParam)
    {
    EnterCriticalSection(
    &cs);//加锁 接下来的代码处理过程中不允许其他线程进行操作,除非遇到LeaveCriticalSection
    for(int i = 0; i<10; i++){
    n_AddValue
    ++;
    cout
    << "n_AddValue in FirstThread is "<<n_AddValue <<endl;
    }
    LeaveCriticalSection(
    &cs);//解锁 到EnterCriticalSection之间代码资源已经释放了,其他线程可以进行操作
    return 0;
    }
    //第二个线程
    UINT SecondThread(LPVOID lParam)
    {
    EnterCriticalSection(
    &cs);//加锁
    for(int i = 0; i<10; i++){
    n_AddValue
    ++;
    cout
    << "n_AddValue in SecondThread is "<<n_AddValue <<endl;

    }
    LeaveCriticalSection(
    &cs);//解锁
    return 0;
    }

    在主函数添加以下代码

    代码
    int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
    {
    int nRetCode = 0;

    // 初始化 MFC 并在失败时显示错误
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
    {
    // TODO: 更改错误代码以符合您的需要
    _tprintf(_T("错误: MFC 初始化失败\n"));
    nRetCode
    = 1;
    }
    else
    {
    InitializeCriticalSection(
    &cs);//初始化结构CRITICAL_SECTION

    CWinThread
    *pFirstThread,*pSecondThread;//存储函数AfxBeginThread返回的CWinThread指针

    pFirstThread
    = AfxBeginThread(FirstThread,LPVOID(NULL));//启动第一个线程
    pSecondThread = AfxBeginThread(SecondThread,LPVOID(NULL));//启动第二个线程

    HANDLE hThreadHandle[
    2];//
    hThreadHandle[0] = pFirstThread->m_hThread;
    hThreadHandle[
    1] = pSecondThread->m_hThread;

    //等待线程返回
    WaitForMultipleObjects(2,hThreadHandle,TRUE,INFINITE);
    }

    return nRetCode;
    }

    输出:

    n_AddValue in FirstThread is 1
    n_AddValue in FirstThread is 2
    n_AddValue in FirstThread is 3
    n_AddValue in FirstThread is 4
    n_AddValue in FirstThread is 5
    n_AddValue in FirstThread is 6
    n_AddValue in FirstThread is 7
    n_AddValue in FirstThread is 8
    n_AddValue in FirstThread is 9
    n_AddValue in FirstThread is 10
    n_AddValue in SecondThread is 11
    n_AddValue in SecondThread is 12
    n_AddValue in SecondThread is 13
    n_AddValue in SecondThread is 14
    n_AddValue in SecondThread is 15
    n_AddValue in SecondThread is 16
    n_AddValue in SecondThread is 17
    n_AddValue in SecondThread is 18
    n_AddValue in SecondThread is 19
    n_AddValue in SecondThread is 20

    如果把两个线程函数中的EnterCriticalSection和LeaveCriticalSection位置移到for循环中去,线程的执行顺序将会改变
    输出也就跟着改变,如:

    代码
    //第一个线程
    UINT FirstThread(LPVOID lParam)
    {

    for(int i = 0; i<10; i++){
    EnterCriticalSection(
    &cs);//加锁 锁移到for循环内部里
    n_AddValue ++;
    cout
    << "n_AddValue in FirstThread is "<<n_AddValue <<endl;
    LeaveCriticalSection(
    &cs);//解锁
    }
    return 0;
    }

    //第二个线程
    UINT SecondThread(LPVOID lParam)
    {

    for(int i = 0; i<10; i++){
    EnterCriticalSection(
    &cs);//加锁
    n_AddValue ++;
    cout
    << "n_AddValue in SecondThread is "<<n_AddValue <<endl;
    LeaveCriticalSection(
    &cs);//解锁
    }
    return 0;
    }

    其他代码不变,输出的结果如下:

    n_AddValue in FirstThread is 1
    n_AddValue in SecondThread is 2
    n_AddValue in FirstThread is 3
    n_AddValue in SecondThread is 4
    n_AddValue in FirstThread is 5
    n_AddValue in SecondThread is 6
    n_AddValue in FirstThread is 7
    n_AddValue in SecondThread is 8
    n_AddValue in FirstThread is 9
    n_AddValue in SecondThread is 10
    n_AddValue in FirstThread is 11
    n_AddValue in SecondThread is 12
    n_AddValue in FirstThread is 13
    n_AddValue in SecondThread is 14
    n_AddValue in FirstThread is 15
    n_AddValue in SecondThread is 16
    n_AddValue in FirstThread is 17
    n_AddValue in SecondThread is 18
    n_AddValue in FirstThread is 19
    n_AddValue in SecondThread is 20

    个人认为在函数EnterCriticalSection和LeaveCriticalSection中间的代码执行过程不会被其他线程干拢或者这么讲不允许其他线程中
    的代码执行。这样可以有效防止一个全局变量在两个线程中同时被操作的可能性

  • 相关阅读:
    JMeter性能测试中控制业务比例
    软件版本命名规范
    软件测试方法——静态测试与动态测试
    安装BugFree 3.0.4时出现的问题
    Linux下给mysql创建用户分配权限
    LoadRunner 测试脚本
    linux dd命令详解
    Linux查看CPU和内存使用情况
    Error:java: 无效的源发行版: 10
    rf接口自动化之结果校验
  • 原文地址:https://www.cnblogs.com/sevenyuan/p/1911670.html
Copyright © 2011-2022 走看看