1. 程式人生 > >從一個多執行緒的例子,來理解Sleep的機制和用法

從一個多執行緒的例子,來理解Sleep的機制和用法

這個例子是兩個執行緒用於售票,保證輪流售票的有序性。

#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