• 线程锁的概念函数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中间的代码执行过程不会被其他线程干拢或者这么讲不允许其他线程中
    的代码执行。这样可以有效防止一个全局变量在两个线程中同时被操作的可能性

  • 相关阅读:
    exercise 1-6
    第五章 Inheritance继承
    wk1&2 字符串
    <转>Python 多线程的单cpu与cpu上的多线程的区别
    Python字典增删操作技巧简述
    Python 拷贝对象(深拷贝deepcopy与浅拷贝copy)
    <转>Python3.x和Python2.x的区别介绍
    <转>Python运行的17个时新手常见错误小结
    常见测试流程
    <转>数据库设计的三大范式
  • 原文地址:https://www.cnblogs.com/sevenyuan/p/1911670.html
Copyright © 2020-2023  润新知