[英]how to solve busy waiting for many running threads
我寫了一個多線程程序:
#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <fstream>
#include <iostream>
using namespace std;
ofstream myfile;
BYTE lockmem=0x0;
unsigned int __stdcall mythreadA(void* data)
{
__asm
{
mov DL,0xFF
mutex:
mov AL,0x0
LOCK CMPXCHG lockmem,DL
jnz mutex
}
// Enter Critical Section
for (int i = 0; i < 100000; i++)
{
myfile << "." << i << endl;
}
// Exit Critical Section
__asm
{
lock not lockmem
}
return 0;
}
int main(int argc, char* argv[])
{
myfile.open ("report.txt");
HANDLE myhandleA[10];
//int index = 0;
for(int index = 0;index < 100;index++)
{
myhandleA[index] = (HANDLE)_beginthreadex(0, 0, &mythreadA, 0, 0, 0);
}
getchar();
myfile.close();
return 0;
}
在關鍵部分,我編寫內聯代碼,以確保只有一個線程在臨界區。(在這個程序中,我不想使用API和函數來實現臨界區中唯一的一個線程,所以我使用內聯匯編)。 現在我忙着等待問題。因為在一個線程進入臨界區之后,其他線程在關鍵部分之前忙於循環,所以cpu的進程上升了! 在這里,我尋找解決忙碌等待問題的方法。 (我更喜歡使用匯編指令而不是API和任何函數,但我也想知道它們)
你在做什么基本上叫做自旋鎖,它不應該用於長時間的操作。 如您所述,這是消耗CPU時間的預期結果。
但是,您可以基於自旋鎖和condvar / event構建互斥鎖(futex)(快速用戶模式互斥鎖)。
您可以使用阻止必須等待的線程的內核API調用,或者您可以浪費CPU周期和內存帶寬來保持您的風扇全速運行並使辦公室保持溫暖。
沒有任何其他選擇。
如果我理解你的問題和程序正確,你的程序中有幾個問題。 其他人也在上面的帖子中提到過這一點。
您的實際關鍵部分代碼非常慢,因為您在文件的新行中寫入數字達100000次。 文件I / O操作將非常慢,在您的情況下,這是您的線程函數正在執行的操作。 我不太了解您在程序中使用的匯編指令,但看起來這些鎖定機制代碼正在為剩余的線程創建繁忙的等待代碼,這些代碼尚未安排執行。 如上所述,您應該開始使用基於Microsoft的系統上提供的EnterCriticalSection()和LeaveCriticalSection()API。 這些API在內部處理任何事情(一般不能從我們自己的邏輯中實現),因此在等待時不會有任何CPU峰值。
如果您仍想使用當前邏輯執行某些操作,我認為您應該使用/實現某種形式的sleep()類型函數,該函數應該執行並嘗試。 這將確保由於連續執行/檢查某些標志而不會有任何CPU忙時間情況。
Calvin還提到你應該嘗試分配鎖而不是中央鎖。 我們應該記住一件事,如果我們的任務很簡單並且可以通過傳統的單線程方法輕松完成,我們就不應該采用多線程解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.