线程--时间片

/*
对两个线程进行轮流操作。
一个线程输出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一定发生翻转,经验证,有些时候不会出现轮流输出。

 

posted @ 2017-06-27 23:51  gd_沐辰  阅读(2922)  评论(0编辑  收藏  举报