從一個多執行緒的例子,來理解Sleep的機制和用法
阿新 • • 發佈:2019-01-08
這個例子是兩個執行緒用於售票,保證輪流售票的有序性。
#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