zoukankan      html  css  js  c++  java
  • windows多线程同步--信号量

    推荐参考博客:秒杀多线程第八篇 经典线程同步 信号量Semaphore

     

    首先先介绍和windows信号量有关的两个API:创建信号量、释放信号量

     

    HANDLE WINAPI CreateSemaphore(               msdn官网解释
      _In_opt_  LPSECURITY_ATTRIBUTES lpSemaphoreAttributes
      _In_      LONG lInitialCount,
      _In_      LONG lMaximumCount,
      _In_opt_  LPCTSTR lpName
    );
    第一个参数:安全属性,如果为NULL则是默认安全属性
    第二个参数:信号量的初始值,要>=0且<=第三个参数
    第三个参数:信号量的最大值
    第四个参数:信号量的名称
    返回值:指向信号量的句柄,如果创建的信号量和已有的信号量重名,那么返回已经存在的信号量句柄

     

    BOOL WINAPI ReleaseSemaphore(             msdn官网解释
      _In_       HANDLE hSemaphore,
      _In_       LONG lReleaseCount,
      _Out_opt_  LPLONG lpPreviousCount
    );
    第一个参数:信号量句柄
    第二个参数:释放后,信号量增加的数目
    第三个参数:信号量增加前的值存放的地址,如果不需要则为NULL
    返回值:释放是否成功

     

    以上两个函数头文件:windows.h (另外还有个函数OpenSemaphore()可以打开其它进程创建的信号量)                                      本文地址

     

    下面通过一个例子来说明信号量如何使用,这是一道IT公司笔试题:编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。

    分析:这里我们要让三个线程按顺序依次打印ABC,即当一个线程在打印A时,另外两个线程不能够打印,而且打印完A以后,接下来必须打印B。我们使用三个信号量分别控制A B C的打印,打印完A就释放B的信号量,打印完B就释放C的信号量,打印完C就释放A的信号量。具体见下面代码:

     #include<string>
     #include<iostream>
     #include<process.h>
     #include<windows.h>
     using namespace std;
     HANDLE hsem1,hsem2,hsem3;
    
    //线程绑定的函数返回值和参数是确定的,而且一定要__stdcall
    unsigned __stdcall threadFunA(void *)
    {
        for(int i = 0; i < 10; i++){
            WaitForSingleObject(hsem1, INFINITE);//等待信号量
            cout<<"A";
            ReleaseSemaphore(hsem2, 1, NULL);//释放信号量
        }
        return 1;
    }
    unsigned __stdcall threadFunB(void *)
    {
        for(int i = 0; i < 10; i++){
            WaitForSingleObject(hsem2, INFINITE);//等待信号量
            cout<<"B";
            ReleaseSemaphore(hsem3, 1, NULL);//释放信号量
        }
        return 2;
    }
    unsigned __stdcall threadFunC(void *)
    {
        for(int i = 0; i < 10; i++){
            WaitForSingleObject(hsem3, INFINITE);//等待信号量
            cout<<"C";
            ReleaseSemaphore(hsem1, 1, NULL);//释放信号量
        }
        return 3;
    }
    
    
    int main()
    {
        //创建信号量
        hsem1 = CreateSemaphore(NULL, 1, 1, NULL);
        hsem2 = CreateSemaphore(NULL, 0, 1, NULL);
        hsem3 = CreateSemaphore(NULL, 0, 1, NULL);
    
        HANDLE hth1, hth2, hth3;
    
        //创建线程
        hth1 = (HANDLE)_beginthreadex(NULL, 0, threadFunA, NULL, 0, NULL);
        hth2 = (HANDLE)_beginthreadex(NULL, 0, threadFunB, NULL, 0, NULL);
        hth3 = (HANDLE)_beginthreadex(NULL, 0, threadFunC, NULL, 0, NULL);
    
        //等待子线程结束
        WaitForSingleObject(hth1, INFINITE);
        WaitForSingleObject(hth2, INFINITE);
        WaitForSingleObject(hth3, INFINITE);
    
        //一定要记得关闭线程句柄
        CloseHandle(hth1);
        CloseHandle(hth2);
        CloseHandle(hth3);
        CloseHandle(hsem1);
        CloseHandle(hsem2);
        CloseHandle(hsem3);
    }

     

    信号量没有线程所有权属性,即一个线程获得某个信号量后,在他释放该信号量之前,他不能再次进入信号量保护的区域

    【版权声明】转载请注明出处http://www.cnblogs.com/TenosDoIt/p/3601252.html

  • 相关阅读:
    [Bug] .NET 2.0 的Bug —— ComboBox中不能添加Component.
    [WPF]WPF中如何实现数据与表示分离。(一) —— XAML
    我有2个Windows Live Messenger的邀请。
    Avalon学习笔记 之 路由事件
    [FxCop.设计规则]10. 类型应该被声明在命名空间中
    Avalon学习笔记(二)——从属属性 和 附加属性
    Longhorn将集成RSS支持。
    [WinFX]WinFX 12月份CTP发布,其中包含了XAML设计器
    [FxCop.设计规则]9. 事件句柄声明不恰当
    对于最近一段时间热门的新技术的感想
  • 原文地址:https://www.cnblogs.com/TenosDoIt/p/3601252.html
Copyright © 2011-2022 走看看