關於執行緒同步的實現機制---busy waiting
阿新 • • 發佈:2019-01-31
第一種執行緒同步機制:只利用一個全域性變數來判斷是否有執行緒正在使用critical section,這樣就有可能出現,兩個執行緒同時判斷當前沒有執行緒正在使用critical section的情況,從而同時進入了critical section。
實際結果輸出:偶爾出現加減交替的情況,即偶爾出現了兩個執行緒同時進入critical section的情況。
#include <stdio.h>
#include <Windows.h>
#include <iostream>
using namespace std;
int id = 0;
int x = 0 ;
int length = 10000;
DWORD WINAPI cc(PVOID pvParam);
bool test(int &id) {
if (id == 0) {
id = 1;
return true;
}
else
return false;
}
int main(void)
{
DWORD dwThreadID;
HANDLE hThread = CreateThread(NULL, 0, cc, (PVOID)id, 0, &dwThreadID);
while (1) {
while (test(id));
for (int i = 0; i < length; i++)
{
x++;
}
printf("0 : %d\n\n", x);
id = 0;
}
}
DWORD WINAPI cc(PVOID pvParam) {
while (1) {
while (test(id));
for (int i = 0; i < length; i++)
{
x--;
}
printf("1 : %d\n\n" , x);
id = 0;
}
}
第二種執行緒同步機制:在每個執行緒中都判斷了另一個執行緒是否正在使用critical section。
實驗結果輸出:基本上第一個執行緒執行一次就到第二個執行緒執行一次。
#include <iostream>
#include <Windows.h>
#include <stdio.h>
using namespace std;
int id = 0;
int x = 0;
int length = 10000;//重複10000次是為了讓執行緒同步的問題出現得更明顯
bool flag[2] = { false, false };
DWORD WINAPI cc(PVOID pvParam);
int main(void)
{
DWORD dwThreadID;
HANDLE hThread = CreateThread(NULL, 0, cc, (PVOID)id, 0, &dwThreadID);
while (1) {
id = 1;
flag[0] = true;
//判斷第二個程序是否正在使用全域性變數x
while (flag[1] && id);
//critical section
for (int i = 0; i < length; i++)
{
x++;
}
printf("0 : %d\n\n", x);
flag[0] = false;
}
}
DWORD WINAPI cc(PVOID pvParam) {
while (1) {
id = 0;
flag[1] = true;
//判斷第一個程序是否正在使用全域性變數x
while (flag[0] && id == 0);
//critical section
for (int i = 0; i < length; i++)
{
x--;
}
printf("1 : %d\n\n", x);
flag[1] = false;
}
}
結論:在處理執行緒同步的問題時,要設計更加嚴謹的判斷機制。