题目要求:
子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码。
分析:
申请两个事件对象保持两个线程同步(先子线程循环10次,再主线程100次,然后将两次循环共循环50次)!
SetEvent(),将事件对象设置为有信号
ResetEvent(),将事件对象设置为无信号
WaitForSingleObject(),有信号才能被申请。
a)子线程先执行,则子线程的事件对象必须有信号,而主线程无信号!
b)子线程执行完一次10次循环后,则将子线程事件对象无信号,将主线程事件对象有信号(准备被申请并执行主线程循环)。
c)主线程执行完一次100次循环后,则将主线程事件对象无信号,将子线程事件对象有信号(准备被申请并执行子线程循环)
d)如此往复50次上诉行为。
具体代码如下:
#include <windows.h>
#include <process.h> // for _beginthread()
//线程函数
unsigned int __stdcall Fun(void *pPM);
//线程数量
const int THREAD_NUM = 1;
//循环次数
const int LOOP = 50;
//两个互斥事件
HANDLE g_hmainEvent;
HANDLE g_hsubEvent;
int main()
{
HANDLE hdl[THREAD_NUM];
//创建事件对象
g_hmainEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//该行第二个参数表示手动处理事件对象的信号状态
g_hsubEvent = CreateEvent(NULL, TRUE, TRUE, NULL);//该行第三个参数表示该事件对象已触发
hdl[0] = (HANDLE)_beginthreadex(
NULL, //为确定的 SECURITY_ATTRIBUTES 结构的指针返回的句柄是否可由子进程继承。 如果为 null,句柄不能被继承。
0, //新线程的堆栈大小,可以为0
Fun, //线程函数
NULL, //参数列表传递到新线程或 NULL。
0, //新的挂起的线程 (运行的0 或 CREATE_SUSPENDED ) 的初始状态;使用 ResumeThread 执行线程。
NULL);//Thread ID
for (int i = 0; i < LOOP; i++)
{
WaitForSingleObject(g_hmainEvent, INFINITE);//申请有信号的事件对象
ResetEvent(g_hmainEvent);//设置事件对象没触发
cout << " 主线程开始循环(次数) ";
int cnt = 100;
while (cnt > 0) cout << 101 - cnt-- << " ";
cout << endl;
SetEvent(g_hsubEvent);//设置事件对象已触发
}
CloseHandle(g_hsubEvent);
CloseHandle(g_hmainEvent);
for (int i = 0; i < THREAD_NUM; i++)
CloseHandle(hdl[i]);
getchar();
return 0;
}
unsigned int __stdcall Fun(void *pPM)
{
for (int i = 0; i < LOOP; i++)
{
WaitForSingleObject(g_hsubEvent, INFINITE);
ResetEvent(g_hsubEvent);
cout << " 子线程开始循环(次数) ";
int cnt = 10;
while (cnt > 0) cout << 11 - cnt-- << " ";
cout << endl;
SetEvent(g_hmainEvent);
}
return 0;
}