zoukankan      html  css  js  c++  java
  • 创建互斥对象同步线程

        互斥对象(mutex)属于内核对象,它能够确保线程拥有对单个资源的互斥访问权。互斥对象包含一个使用数量,一个线程ID和一个计数器。其中ID用于表示系统中的哪个线程当前拥有互斥对象,计数器用于指明该线程拥有互斥对象的次数。

    #include<windows.h>
    #include<iostream.h>
    DWORD WINAPI fun1proc(LPVOID lpParameter);
    DWORD WINAPI fun2proc(LPVOID lpParameter);
    int index=0;
    int tickets=100;
    HANDLE hMutex;

    void main()
    {
    HANDLE hThread1;
    HANDLE hThread2;
       hThread1=CreateThread(NULL,0,fun1proc,NULL,0,NULL);
    hThread2=CreateThread(NULL,0,fun2proc,NULL,0,NULL);
       CloseHandle(hThread1);
    CloseHandle(hThread2);

    //第一个参数NULL让互斥对象适应默认的安全性,FALSE创建互斥对象的线程不对
    //互斥对象具有所有权,也就是互斥对象无所有权。
    //第三个参数创建一个匿名的互斥对象
       hMutex=CreateMutex(NULL,FALSE,NULL); //创建互斥对象
       Sleep(4000);
    }

    DWORD WINAPI fun1proc(LPVOID lpParameter)
    {
    while(1)
    {
       WaitForSingleObject(hMutex,INFINITE);
       if(tickets>0)
       {
        Sleep(1);
        cout<<"thread1 sell ticket"<<tickets--<<endl;
       }
       else
        break;
        ReleaseMutex(hMutex);
    }
    return 0;
    }

    DWORD WINAPI fun2proc(LPVOID lpParameter)
    {
    while(1)
    {
       WaitForSingleObject(hMutex,INFINITE);
       if(tickets>0)
       {
        Sleep(1);
        cout<<"thread2 sell ticket"<<tickets--<<endl;
       }
       else
        break;
        ReleaseMutex(hMutex);
    }
    return 0;
    }

    代码执行顺序

    在创建互斥对象时,第二个参数传递的是FALSE值,这表明当前没有线程拥有这个互斥对象,于是操作系统会将该互斥对象设置为有信号状态。当第一个线程开始运行时,进入while循环后,调用WaitForSingleObject函数,因为这个互斥对象处于有信号状态,所以两个线程总有个一个会请求到这个互斥对象。

    比如线程1请求到了互斥对象,操作系统会将该互斥对象的线程ID设置为线程1的ID,接着操作系统会将这个互斥对象设置为未通知状态。线程1继续往下运行,调用Sleep函数,于是暂停执行。操作系统就会选择线程2开始执行,进入while循环后,调用WaitForSingleOBject函数,但这时该互斥对象已经被线程1所用有,处于未通知状态,线程2没有获得互斥对象的所有权,因此WaitForSingle函数就会处于等待状态,从而导致线程2处于暂停状态。当线程1的睡眠时间到以后,线程1将会继续执行,即销售一张火车票。

    这时线程1执行到调用ReleaseMutex函数释放互斥对象的所有权,也就是让互斥象处于通知状态。互斥对象的一个循环走完。两个线程又处于同一起点开始请求互斥对象。

  • 相关阅读:
    计算openlayers两点之间的距离
    node.js Tools for Visual Studio 介绍
    spring.net (3)依赖注入基础
    spring.net (2)环境搭建 对(1)例子的解释和扩充
    spring.net (1) 概念-控制反转(又名依赖注入)
    如何去定义一个jquery插件
    entityframework lamda 使用where时的注意事项
    k8s big-ip control 安装使用
    lb的keepalive问题
    firefox的fq设置图文教程- 【windows,mac通用】
  • 原文地址:https://www.cnblogs.com/yuzhould/p/4455031.html
Copyright © 2011-2022 走看看