• vc++高级班之多线程篇[6]---线程间的同步机制①


    ①、线程同步的必要性:
     
    int g_Num = 0;
    UINT __cdecl ThreadProc(LPVOID lpParameter)
    {
     for (int idx = 0; idx < 100; ++idx) {
      g_Num = g_Num+1;
      CString strNum;
      strNum.Format(_T("%d"), g_Num);
      g_Num = g_Num-1;
     }
     return 0;
    }
     
    void CThreadTestDlg::OnBnClickedBtn()
    {
     for (int idx = 1; idx <= 50; ++idx) {
      AfxBeginThread(ThreadProc, NULL);
     }
    }
    void CThreadTestDlg::OnBnClickedPrintBtn()
    {
     int realNum = g_Num;
    }
     
    ///////////////////////////////////////////////////////////////////////////////
     
    CStringArray g_ArrString;
    UINT __cdecl ThreadProc(LPVOID lpParameter)
    {
     int startIdx = (int)lpParameter;
     for (int idx = startIdx; idx < startIdx+100; ++idx) {
      CString str;
      str.Format(_T("%d"), idx);
      g_ArrString.Add(str);
     }
     return 0;
    }
     
    void CThreadTestDlg::OnBnClickedBtn()
    {
     for (int idx = 1; idx <= 50; ++idx) {
      AfxBeginThread(ThreadProc, (LPVOID)(idx*10));
     }
    }
     
    void CThreadTestDlg::OnBnClickedPrintBtn()
    {
     CString strCount;
     INT_PTR nCount = g_ArrString.GetCount();
     strCount.Format(_T("%d"), nCount);
     MessageBox(strCount);
     
     for (INT_PTR idx = 0; idx < nCount; ++idx) {
      OutputDebugString(g_ArrString.GetAt(idx));
     }
    }
    ===================================================
    ②、原子互锁家族函数:
    1、InterlockedIncrement:加1操作;
    2、InterlockedDecrement:减1操作;
    3、InterlockedExchangeAdd:加上“指定”的值,可以加上一个负数;
    4、InterlockedExchange、InterlockedExchangePointer:能够以原子操作的方式用第二个参数的值来取代第一个参数的值;
    ===================================================
    其他互锁家族的函数大家也可以参考下MSDN,理解理解意思!
    一般情况下,在多线程编程中如果对某一个变量的值进行改变的话,使用以上互锁函数确实比较方便,但有很多时候多线程间会操作更为复杂的东西
    比如对一个结构的赋值、对链表的插入与删除 等等,以上互锁函数不能满足要求,所以要使用更为高级的多线程间的同步技术!
    ===================================================
    ③、Critical Sections(关键代码段、关键区域、临界区域)
     
    使用方法:
    1、初始化:InitializeCriticalSection;
    2、删除:DeleteCriticalSection;
    3、进入:EnterCriticalSection(可能造成阻塞);
    4、尝试进入:TryEnterCriticalSection(不会造成阻塞);
    5、离开:LeaveCriticalSection;
     
    固有特点(优点+缺点):
    1、是一个用户模式的对象,不是系统核心对象;
    2、因为不是核心对象,所以执行速度快,有效率;
    3、因为不是核心对象,所以不能跨进程使用;
    4、可以多次“进入”,但必须多次“退出”;
    5、最好不要同时进入或等待多个 Critical Sections,容易造成死锁;
    6、无法检测到进入到 Critical Sections 里面的线程当前是否已经退出!
    ===================================================
    ※※※ 小作业:
    MFC中同样对 Critical Sections 进行了封装,所以尝试使用 CCriticalSection 类进行线程间的同步将更为方便!
    ------------------------------------- End -------------------------------------------
  • 相关阅读:
    出现org.apache.ibatis.binding.BindingException异常
    EasyExcel读写操作
    window下运行nginx出现nginx: [emerg] bind() to 0.0.0.0:80 failed (10013: An attempt was made to access a socket in a way forbidden by its access permissions)
    vue Module build failed: Error: Missing binding E:vuevue-demo ode_modules ode-sa ssvendorwin64
    Axios谷粒学院学习
    springboot中数据库的连接
    多表删除,删除一个表的同时删除中间表
    今天写了一个SSM小项目,运行之后,前端页面的CSS、js样式显示不出来,具体操作如下:
    Java中Iterator(迭代器)实现原理
    写一些东西,记录一下成长的过程
  • 原文地址:https://www.cnblogs.com/liaocheng/p/4243409.html
Copyright © 2020-2023  润新知