从一个多线程的例子,来理解Sleep的机制和用法

本文通过两个线程模拟售票过程,介绍了如何利用Windows API中的互斥锁(Mutex)来实现线程间的同步,确保售票操作的正确性和有序性。同时讨论了Sleep函数的使用及其对CPU利用率的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个例子是两个线程用于售票,保证轮流售票的有序性。

#include <windows.h>
#include <iostream>
DWORD WINAPI Fun1Proc(LPVOID lpParameter);//线程1
DWORD WINAPI Fun2Proc(LPVOID lpParameter);//线程2
int tickets=60000;//总票数
HANDLE hMutex;
//主函数
void main()
{
  HANDLE hThread1;
    HANDLE hThread2;
    hMutex=CreateMutex(NULL,TRUE,"tickets"); //创建互斥锁
    //...省略对锁创建是否成功的检查
    ReleaseMutex(hMutex);    //释放该互斥锁,否则子线程得不到该锁,子线程一直WaitForSingleObject(hMutex,INFINITE);
    hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);    //创建,启动线程1
    hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL) ;   //创建,启动线程2
    CloseHandle(hThread1);  
    CloseHandle(hThread2);
     Sleep(500000);                 //主线程必须有足够的时间保证子线程执行完毕,否则程序崩溃
}
//线程1的入口函数
DWORD WINAPI Fun1Proc(LPVOID lpParameter)
{
  while (true)
    {
       ReleaseMutex(hMutex);
        WaitForSingleObject(hMutex,INFINITE);
     if (tickets>0)
        {
            Sleep(1);
            cout<<"thread1 sell ticket :"<<tickets--<<endl;
        }
        else
            break;
        ReleaseMutex(hMutex);
    }
    return 0;
}
//线程2的入口函数
DWORD WINAPI Fun2Proc(LPVOID lpParameter)
{
    while (true)
    {
       ReleaseMutex(hMutex);
       WaitForSingleObject(hMutex,INFINITE);
        if (tickets>0)
        {
           Sleep(1);
            cout<<"thread2 sell ticket :"<<tickets--<<endl;
        }
        else
            break;
        ReleaseMutex(hMutex);
    }
       return 0;
}

关于使用Sleep的一些看法:
(1)不用Sleep并且线程不阻塞,Sleep(1)可以使得CPU的负荷减少接近40%
(2)Sleep(0)触发操作系统重新进行一个CPU竞争,即重新调度。操作系统监控有线程霸占CPU的情况,  如果发现,就强制挂起该线程。在这个程序中,主线程Sleep(500000),就可以看作是长期霸占CPU的情况。
(3)如果主线程Sleep的时间,不足以执行完子线程的任务,主线程强制退出并释放资源则子线程非正常退出,  于是整个程序崩溃掉。
(4)Sleep的作用是忙等,谁调用它谁就睡觉,时间到了以后该线程进入就绪队列。
其他概念:
(1)wait和Sleep的区别:Sleep一段时间后自己唤醒自己,之后进入到就绪队列,wait在线程池中等待, 需要被迫的notify还需要系统分配资源时间上要比Sleep多一些。
(2)suspend和block不是忙等,碰到后立刻返回。需要另一个外来事件唤醒。
(3)在主线程中CreateMutex,主线程持有Mutex,也就是谁持有谁ReleaseMutex,否则子线程永远得不 到该锁,并且一直等待获取该锁。
     
 欢迎大家在该话题的基础上发表自己的看法,或是改进的意见!
 欢迎访问:http://blog.csdn.net/cuishumao/article/details/10094823

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值