做了一个mfc多线程程序,
先定义两个变量:
volatile BOOL m_running;
volatile bool m_multiThreadend;//多线程是否结束在主线程里调用:
m_running=true;
m_CThread=AfxBeginThread((AFX_THREADPROC)downloadData,this,0,0,0);void WINAPI downloadData(LPVOID lpvoid)
{
while(m_running)
{
/*这里是业务逻辑的代码,关键代码10几行,加了9条打印执行时间的代码
struct _timeb timebuffer;
_ftime(&timebuffer);
FILE *pf = fopen("log.txt","a");
CString s;
s.Format("1: %ld %u\n",timebuffer.time,timebuffer.millitm);
fwrite(s,sizeof(char),s.GetLength(),pf);
fclose(pf);
打印出当前时间的UTC时间,即1970年1月1号午夜到现在的秒数和当前毫秒数。格式类似:
1: 1303000981 443
2: 1303000981 443
3: 1303000981 443
4: 1303000981 443
5: 1303000981 443
6: 1303000981 474
7: 1303000981 526
8: 1303000981 527
9: 1303000981 587
*/
Sleep(60);//60毫秒执行一次。
}
m_multiThreadend=true;//多线程结束掉了。
//这里向log.txt中写入:m_running is false,thread is to be end.
AfxEndThread(0,true);
}void CTestDlg::OnButtonClick()
{
m_running=false;//m_running置为false,上面函数的while循环不满足,就会退出多线程。
//在这里向log.txt中写入:set m_running to false
Sleep(1);//听说sleep可以让当前线程让出cpu,所以加了这句话
bool b=SwitchToThread();//这句按理说也可以切换线程。
//这里将b打印到log.txt中
int i;
while(m_multiThreadend==false&&i<20)//等待2秒让多线程结束
{
Sleep(100);
i++;
}
if(i==20)//2秒全过去了
{
MessageBox("timeout");
//我在这里还加入了往log.txt写记录的语句,输出的格式为201303000983 614 timeout ===================
}else
MessageBox("OK");
}
程序大体就这样,运行程序有时没问题,一切按预计的,多线程被结束掉。可是也有时会出现等待超时的现象。
这时的log.txt打印消息为:
1303000981 612 set m_running to false
==============0=============//这是打印出的b的值,switchtothread返回false
1303000983 614 timeout ===================//OnButtonClick中等待超时了
1: 1303000981 587
2: 1303000981 587
3: 1303000981 587
4: 1303000981 587
5: 1303000981 587//这里和下一句间隔了两秒,看来这个线程在这两秒没有等到CPU时间片。
6: 1303000983 635
7: 1303000983 685
8: 1303000983 685
9: 1303000983 745
17 0:43:3:745 m_running is false,thread is to be end.
由上可以看出,SwitchToThread返回false,可是根据后面的打印消息看出,另一个线程还在运行着呢,为什么切换失败。还有,Sleep不是会让当前线程让出CPU时间吗。为什么有时这段程序正常,有时就结束不掉多线程呢。
先定义两个变量:
volatile BOOL m_running;
volatile bool m_multiThreadend;//多线程是否结束在主线程里调用:
m_running=true;
m_CThread=AfxBeginThread((AFX_THREADPROC)downloadData,this,0,0,0);void WINAPI downloadData(LPVOID lpvoid)
{
while(m_running)
{
/*这里是业务逻辑的代码,关键代码10几行,加了9条打印执行时间的代码
struct _timeb timebuffer;
_ftime(&timebuffer);
FILE *pf = fopen("log.txt","a");
CString s;
s.Format("1: %ld %u\n",timebuffer.time,timebuffer.millitm);
fwrite(s,sizeof(char),s.GetLength(),pf);
fclose(pf);
打印出当前时间的UTC时间,即1970年1月1号午夜到现在的秒数和当前毫秒数。格式类似:
1: 1303000981 443
2: 1303000981 443
3: 1303000981 443
4: 1303000981 443
5: 1303000981 443
6: 1303000981 474
7: 1303000981 526
8: 1303000981 527
9: 1303000981 587
*/
Sleep(60);//60毫秒执行一次。
}
m_multiThreadend=true;//多线程结束掉了。
//这里向log.txt中写入:m_running is false,thread is to be end.
AfxEndThread(0,true);
}void CTestDlg::OnButtonClick()
{
m_running=false;//m_running置为false,上面函数的while循环不满足,就会退出多线程。
//在这里向log.txt中写入:set m_running to false
Sleep(1);//听说sleep可以让当前线程让出cpu,所以加了这句话
bool b=SwitchToThread();//这句按理说也可以切换线程。
//这里将b打印到log.txt中
int i;
while(m_multiThreadend==false&&i<20)//等待2秒让多线程结束
{
Sleep(100);
i++;
}
if(i==20)//2秒全过去了
{
MessageBox("timeout");
//我在这里还加入了往log.txt写记录的语句,输出的格式为201303000983 614 timeout ===================
}else
MessageBox("OK");
}
程序大体就这样,运行程序有时没问题,一切按预计的,多线程被结束掉。可是也有时会出现等待超时的现象。
这时的log.txt打印消息为:
1303000981 612 set m_running to false
==============0=============//这是打印出的b的值,switchtothread返回false
1303000983 614 timeout ===================//OnButtonClick中等待超时了
1: 1303000981 587
2: 1303000981 587
3: 1303000981 587
4: 1303000981 587
5: 1303000981 587//这里和下一句间隔了两秒,看来这个线程在这两秒没有等到CPU时间片。
6: 1303000983 635
7: 1303000983 685
8: 1303000983 685
9: 1303000983 745
17 0:43:3:745 m_running is false,thread is to be end.
由上可以看出,SwitchToThread返回false,可是根据后面的打印消息看出,另一个线程还在运行着呢,为什么切换失败。还有,Sleep不是会让当前线程让出CPU时间吗。为什么有时这段程序正常,有时就结束不掉多线程呢。
解决方案 »
- 用GDI,在极坐标系下 绘制一个角度为30度的圆弧
- 我用CBitmapDialog类只能实现1个的不规则窗体,不能实现多个不规则窗体,请教一下,有什么好办法吗? 100分求解!
- 请问FindFirstFile系列API能处理类似"\\10.0.4.100\\mpeg\\*.*"的远程查找么?
- 我想用 FLASH,却不想使用 MFC,听说直接用 COM 可以实现,求教。
- 谁有API手册,急用
- 这个函数怎么用?inet_addr
- 高手们,我是个VC的新手.看完了孙鑫的VC深入详解教学视频..下一步应该看什么书?
- 非clr下如何使用正则表达式
- 菜鸟搞不定画图板,请高手指点
- vc 初学问题,请各位有识之士指点
- CStdioFile检测结束(无法使用通常的if(NULL=Read....)
- 关于terminatethread的替代方案
改成
unsigned int __cdecl downloadData(LPVOID Parameter)
UINT __cdecl MyControllingFunction( LPVOID pParam );UINT __cdecl downloadData(LPVOID pParam);
1303008172 714 set m_bRun to false
==============0=============
1303008174 716 timeout ===================
1: 1303008172 630
2: 1303008172 630
3: 1303008172 630
4: 1303008172 630
5: 1303008172 630
6: 1303008174 734
7: 1303008174 788
8: 1303008174 789
9: 1303008174 849
DWORD result = WaitForSingleObject(hMutex,100);//第二个参数本来写的是INFINITE,可是会出现程序卡死的现象,换成一个具体的数就会出现timeout的现象。
if(result == WAIT_TIMEOUT)
{
// MessageBox("Timeout");
FILE *pFile = fopen("log.txt","a"); GetSystemTime(&t1);
CString str;
str.Format("%d %u:%u:%u:%u Timeout while waitforsingleobject \n",
t1.wDay,t1.wHour,t1.wMinute,t1.wSecond,t1.wMilliseconds);
if(f!=NULL)
fwrite(str,sizeof(char),str.GetLength(),pFile);
fclose(pFile);
// BOOL b=TerminateThread(m_CEvfThread->m_hThread,0);
}
另外在另一个线程:
while(m_runing)
{
DWORD result = WaitForSingleObject(hMutex,100);//while循环体第一句话
.....
ReleaseMutex(hMutex);
Sleep(60);
}
MSG msg;
DWORD drect = ::MsgWaitForMultipleObjects(1,&m_CThread->m_hThread,false,1000,QS_ALLINPUT);
if(drect == WAIT_OBJECT_0+1)
{
while(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
MessageBox("wait for multipleobject failed");
}
简单的测试了一下,貌似好了。