我有以下程式產生兩個執行緒print_something(),它們都重復列印一個特定的字串:執行緒 1 列印"Hi\n"和執行緒 2 列印"Bye\n":
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *print_something(int *k)
{
int n = 100;
int i;
if (*k) {
for (i = 0; i < 100; i ) {
printf("Hi\n");
}
} else {
for (i = 0; i < 100; i ) {
printf("Bye\n");
}
}
}
int main()
{
int x = 1, y = 0;
pthread_t t1, t2;
pthread_create(&t1, NULL, print_something, &x);
pthread_create(&t2, NULL, print_something, &y);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("End of program.\n");
return 0;
}
我希望它們同步運行,其中終端中的輸出是隨機的,例如:
Hi
Hi
Bye
Hi
Bye
...
但相反,我總是讓執行緒 1 在執行緒 2 開始列印之前先完成列印:
Hi
Hi
...
Hi
Hi
Bye
Bye
...
Bye
Bye
End of program.
為什么第一個執行緒阻止第二個執行緒列印?
uj5u.com熱心網友回復:
為什么第一個執行緒阻止第二個執行緒列印?
誰說屏蔽了?也許啟動一個新執行緒需要足夠長的時間,以至于第一個附加執行緒(與原始執行緒并行運行)在第二個附加執行緒到達嘗試列印任何內容之前完成其列印(到標準輸出的緩沖區)。
另一方面,POSIX 確實指定 stdio 函式對流執行操作,就好像每個流都有一個鎖,執行緒必須在進入函式時獲得鎖,并在退出時釋放鎖。因此,第一個執行緒可能確實通過與 關聯的鎖阻塞了第二個執行緒stdout。
此外,當一個執行緒解鎖一個鎖,然后立即嘗試重新獲取同一個鎖時,該執行緒很有可能立即成功,盡管其他執行緒爭用該鎖。因此,當整個回圈體以獲取鎖開始并以釋放鎖結束時——就像你的代碼中關聯鎖的情況stdout——通常一個執行緒能夠獨占許多鎖回圈迭代。
uj5u.com熱心網友回復:
我希望它們同步運行,其中終端中的輸出是隨機的,例如:
這是一個不合理的期望。如果兩個人每人要裝一百顆螺絲,并且共用一把螺絲刀,你認為他們應該在每顆螺絲后交出螺絲刀嗎?只有當拿著螺絲刀的人累了時,才把螺絲刀交出來才有意義。
每個執行緒的絕大部分時間都在訪問控制臺輸出流。它只能通過排除其他執行緒來做到這一點。您期望的行為將是殘暴的。
它們會在同一個核心上運行嗎?這將需要在每一行輸出之后進行背景關系切換——這段代碼的性能可能是最差的。他們會在兩個核心上運行嗎?這意味著每個核心都在等待另一個核心完成控制臺大約一半的時間——這也是可怕的性能。
簡而言之,您希望您的系統找到一種糟糕的方式來執行您要求它執行的操作。它找到了一種更有效的方法——讓一個執行緒保留控制臺,完成它正在做的事情,然后讓另一個執行緒離開。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/410328.html
標籤:
上一篇:OpenMP中的默認變數范圍
