線程--時間片


/*
對兩個線程進行輪流操作。
一個線程輸出1-100
第二個線程輸出101-200
結果:1
101
2
102
。。。。。。。
*/

#include "stdafx.h"
#include <Windows.h>

DWORD WINAPI Thread1(LPVOID lParam)
{
for (int i = 1; i <= 100; ++i)
{
_tprintf(TEXT("Thread1=%d\n"), i);
}
return 0;
}
DWORD WINAPI Thread2(LPVOID lParam)
{
for (int j = 101; j <= 200; ++j)
{
_tprintf(TEXT("Thread2=%d\n"), j);
}
return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThead[2];
hThead[0] = CreateThread(nullptr, 0, Thread1, NULL, 0, nullptr);
//Sleep(1);
hThead[1] = CreateThread(nullptr, 0, Thread2, NULL, 0, nullptr);
WaitForMultipleObjects(sizeof(hThead)/sizeof(HANDLE), hThead, TRUE, INFINITE);
getchar();
return 0;
}

 

第一種情況:

可以看出,以上的操作只是普通的輸出,而且是按1-200輸出。


第二種情況:
hThead[0] = CreateThread(nullptr, 0, Thread1, NULL, 0, nullptr);
Sleep(1);
hThead[1] = CreateThread(nullptr, 0, Thread2, NULL, 0, nullptr);

在線程1后停留1ms,發現:又出現兩個結果:
第一:如第一種情況,按順序輸出。
第二:線程只輸出,可能是33或80(不確定位置),再完整地輸出線程2,再輸出線程1.

 

那么第二種情況,為什么會出現兩個不同的結果?
原因:
重點:當遇到阻塞,當前線程會休眠。又因為CPU永在搶棧式工作,所以CPU隨機運行進程中的線程。
當線程1占用CPU時間到了,就會返回主線程。運行Sleep(),這時就出現了阻塞,CPU會隨機地選擇
其中一條線程進行運行。

第三情況:
在每一個線程輸出后,再Sleep(),使當前線程休眠,轉到其他線程。
如:
_tprintf(TEXT("Thread1=%d\n"), i);
Sleep(1);

結果發現:線程1輸出1,線程2輸出101、102,線程1輸出2.。。。
可以看到線程1和線程2雖然是錯開輸出的,但不是我們所要的。


改善方法:
改進:利用信號,對指定的線程進行操作。

#include "stdafx.h"
#include <Windows.h>

//標志號
enum{
No1,
No2,
};
DWORD g_dwNum = 0;

DWORD WINAPI Thread1(LPVOID lParam)
{
for (int i = 1; i <= 100; ++i)
{
while (g_dwNum != No1)
{    
Sleep(1);    
}    
_tprintf(TEXT("Thread1=%d\n"), i);
g_dwNum = No2;

}
return 0;
}
DWORD WINAPI Thread2(LPVOID lParam)
{
for (int j = 101; j <= 200; ++j)
{
while (g_dwNum != No2)
{    
Sleep(1);
}
_tprintf(TEXT("Thread2=%d\n"), j);
g_dwNum = No1;
}
return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThead[2];
g_dwNum = No1;
hThead[0] = CreateThread(nullptr, 0, Thread1, NULL, 0, nullptr);
//Sleep(1);
hThead[1] = CreateThread(nullptr, 0, Thread2, NULL, 0, nullptr);
//等待所有子線程結束
WaitForMultipleObjects(sizeof(hThead)/sizeof(HANDLE), hThead, TRUE, INFINITE);
getchar();
return 0;
}

注意:此處while (g_dwNum != No1),為什么不用if?
如果使用了if無法確保g_dwNum一定發生翻轉,經驗證,有些時候不會出現輪流輸出。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM