一个多线程面试题的解答
来源:互联网 发布:apache php mysql搭建 编辑:程序博客网 时间:2024/04/29 02:28
多线程的题目要求:
编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,
要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。
备注:该面试题摘自http://blog.csdn.net/morewindows/article/details/7392749
解答思路:
定义三个事件,A事件用来触发线程A,B事件用来触发线程B,C事件用来触发线程C。初始化时,事件A设置为通知状态即执行线程A,并把事件B置为通知状态,同时也A事件复位。线程B等待B事件,事件通知就执行线程B,并把事件C置为通知状态,同时也B事件复位。线程C等待C事件,事件通知就执行线程C,并把事件A置为通知状态,同时也C事件复位。线程退出的条件为线程执行了10次。
下图为线程A、B、C的触发示意图:
以下为实现的代码:
#include "stdafx.h"
#include <wtypes.h>
#define DELAY_SECONDS 1000
//线程的入口参数
typedef struct tagThreadParam
{
HANDLE hAEvent;
HANDLE hBEvent;
HANDLE hCEvent;
DWORD dwThreadId;
}STThreadParam, *PSTThreadParam;
//线程A的处理函数
static UINT ThreadAProc(LPVOID pParam);
//线程B的处理函数
static UINT ThreadBProc(LPVOID pParam);
//线程C的处理函数
static UINT ThreadCProc(LPVOID pParam);
static int MultiThreadDemo(void);
//打印的最大次数
const int nMaxPrintNum = 10;
/*
编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,
要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。
*/
int _tmain(int argc, _TCHAR* argv[])
{
int i = 0;
MultiThreadDemo();
scanf("%d", &i);
return 0;
}
static int MultiThreadDemo(void)
{
//线程句柄
HANDLE hThreadA = NULL;
HANDLE hThreadB = NULL;
HANDLE hThreadC = NULL;
//事件的句柄
HANDLE hAEvent = NULL;
HANDLE hBEvent = NULL;
HANDLE hCEvent = NULL;
//线程参数
STThreadParam stThreadAParam;
STThreadParam stThreadBParam;
STThreadParam stThreadCParam;
printf("MultiThreadDemo\n");
hAEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
hBEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
hCEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
stThreadAParam.dwThreadId = 0;
stThreadAParam.hAEvent = hAEvent;
stThreadAParam.hBEvent = hBEvent;
stThreadAParam.hCEvent = hCEvent;
stThreadBParam = stThreadAParam;
stThreadCParam = stThreadAParam;
hThreadA = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadAProc, (LPVOID)(&stThreadAParam),
CREATE_SUSPENDED, NULL);
hThreadB = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadBProc, (LPVOID)(&stThreadBParam),
CREATE_SUSPENDED, NULL);
hThreadC = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadCProc, (LPVOID)(&stThreadCParam),
CREATE_SUSPENDED, NULL);
SetEvent(hAEvent);
ResumeThread(hThreadA);
ResumeThread(hThreadB);
ResumeThread(hThreadC);
//必须要加延时,如果不加延时会得不到期望的输出结果
Sleep(DELAY_SECONDS);
CloseHandle(hAEvent);
CloseHandle(hBEvent);
CloseHandle(hCEvent);
CloseHandle(hThreadA);
CloseHandle(hThreadB);
CloseHandle(hThreadC);
return true;
}
//线程A的处理函数
static UINT ThreadAProc(LPVOID pParam)
{
int nCount = 0;
PSTThreadParam pThreadParam = NULL;
if(pParam == NULL)
{
return false;
}
pThreadParam = (PSTThreadParam)pParam;
while(true)
{
WaitForSingleObject(pThreadParam->hAEvent, INFINITE);
nCount++;
printf("ThreadA=%d\n", GetCurrentThreadId());
if(nCount >= nMaxPrintNum)
{
SetEvent(pThreadParam->hBEvent);
break;
}
ResetEvent(pThreadParam->hAEvent);
SetEvent(pThreadParam->hBEvent);
}
return true;
}
//线程B的处理函数
static UINT ThreadBProc(LPVOID pParam)
{
int nCount = 0;
PSTThreadParam pThreadParam = NULL;
if(pParam == NULL)
{
return false;
}
pThreadParam = (PSTThreadParam)pParam;
while(true)
{
WaitForSingleObject(pThreadParam->hBEvent, INFINITE);
nCount++;
printf("ThreadB=%d\n", GetCurrentThreadId());
if(nCount >= nMaxPrintNum)
{
SetEvent(pThreadParam->hCEvent);
break;
}
ResetEvent(pThreadParam->hBEvent);
SetEvent(pThreadParam->hCEvent);
}
return true;
}
//线程C的处理函数
static UINT ThreadCProc(LPVOID pParam)
{
int nCount = 0;
PSTThreadParam pThreadParam = NULL;
if(pParam == NULL)
{
return false;
}
pThreadParam = (PSTThreadParam)pParam;
while(true)
{
WaitForSingleObject(pThreadParam->hCEvent, INFINITE);
nCount++;
printf("ThreadC=%d\n", GetCurrentThreadId());
if(nCount >= nMaxPrintNum)
{
SetEvent(pThreadParam->hAEvent);
break;
}
ResetEvent(pThreadParam->hCEvent);
SetEvent(pThreadParam->hAEvent);
}
return true;
}
本代码已在VS2008上运行过。
- 一个多线程面试题的解答
- 多线程的面试题解答(一)
- 一个多线程的面试题
- 网上的一个面试题 (c#)(配有解答)
- 网上的一个面试题 (c#)(配有解答)
- 一个赌博面试题的研究(未解答出来)
- 多线程相关面试题及其解答
- Linux一个多线程的面试题
- Linux一个多线程的面试题
- 多线程中出现的一个面试题
- 百度面试题的解答
- 一些面试题的解答
- 一道面试题的解答
- 华为的一道面试题的解答
- 一道有意思的面试题的解答
- 收藏的面试题及解答
- 解答Google的一道面试题
- 解答Google的一道面试题
- java的四种文件写入方法比较
- c#给线程传递参数的方法
- 第十周任务二
- 面向对象思想解决的问题以及面向对象的三个特征
- 排序算法浅析(一)比较排序算法
- 一个多线程面试题的解答
- 【Android Training - 09】高效地显示Bitmap图片 [ Lesson 3 - 两种缓存Bitmap的方式 ]
- 告别编程5年再次回归,我注意到很多变化
- Memory ordering in some architectures
- 系统崩溃之后
- C++实现判断输入的数组是否是升序的程序
- 第十周任务三
- eWebEditor
- Lua For Windows 环境配置及使sciTE支持中文,使用editplus作为编辑工具