在一个线程中:
void CMainFrame::OnPlay()
{
...
g_bThreadStop = false;// 线程运行标记
DWORD dwThreadID;
m_hThread = CreateThread(NULL,0,FLSTrainThread,NULL,0,&dwThreadID);
...
}void CMainFrame::OnStop()
{
g_bThreadStop=true; // 设置停止标记
DWORD dwRet=WaitForSingleObject(m_hThread,1000*5); //等待5秒
if(dwRet==WAIT_OBJECT_0)// 线程成功结束
{
...
}
if(dwRet==WAIT_TIMEOUT) //超时
{
// MessageBox("非正常结束线程!"); ------(1)
TerminateThread(m_hThread,-1);
}
}DWORD WINAPI FLSTrainThread(LPVOID lpParameter)
{
while(!g_bThreadStop)
{
...
}
AfxMessageBox("成功结束线程!");
return 0;
}
问题1:当执行OnStop的时候,g_bThreadStop已经置为false了,为什么FLSTrainThread并没有
执行AfxMessageBox("成功结束线程!"),而是进入if(dwRet==WAIT_TIMEOUT)内部?如果在加入(1)的代码,那么会先后执行MessageBox("非正常结束线程!");
AfxMessageBox("成功结束线程!"); 真是奇怪!
问题2:我想在CreateThread,调用FLSTrainThread的时候,想向FLSTrainThread传入一个整数
参数,我如下的做法为什么不可以?该怎么做?
int Index=100;
CreateThread(NULL,0,FLSTrainThread,&Index,0,&dwThreadID);
然后在
DWORD WINAPI FLSTrainThread(LPVOID lpParameter)
{
int index = *lpParameter; //为什么不可以?
...
}
void CMainFrame::OnPlay()
{
...
g_bThreadStop = false;// 线程运行标记
DWORD dwThreadID;
m_hThread = CreateThread(NULL,0,FLSTrainThread,NULL,0,&dwThreadID);
...
}void CMainFrame::OnStop()
{
g_bThreadStop=true; // 设置停止标记
DWORD dwRet=WaitForSingleObject(m_hThread,1000*5); //等待5秒
if(dwRet==WAIT_OBJECT_0)// 线程成功结束
{
...
}
if(dwRet==WAIT_TIMEOUT) //超时
{
// MessageBox("非正常结束线程!"); ------(1)
TerminateThread(m_hThread,-1);
}
}DWORD WINAPI FLSTrainThread(LPVOID lpParameter)
{
while(!g_bThreadStop)
{
...
}
AfxMessageBox("成功结束线程!");
return 0;
}
问题1:当执行OnStop的时候,g_bThreadStop已经置为false了,为什么FLSTrainThread并没有
执行AfxMessageBox("成功结束线程!"),而是进入if(dwRet==WAIT_TIMEOUT)内部?如果在加入(1)的代码,那么会先后执行MessageBox("非正常结束线程!");
AfxMessageBox("成功结束线程!"); 真是奇怪!
问题2:我想在CreateThread,调用FLSTrainThread的时候,想向FLSTrainThread传入一个整数
参数,我如下的做法为什么不可以?该怎么做?
int Index=100;
CreateThread(NULL,0,FLSTrainThread,&Index,0,&dwThreadID);
然后在
DWORD WINAPI FLSTrainThread(LPVOID lpParameter)
{
int index = *lpParameter; //为什么不可以?
...
}
解决方案 »
- 网络编程中,在数据链路层抓数据在显示出来这么慢
- 有了.NET为什么还要MFC
- try catch 与 _try _except __finally的区别在哪里呢?讨论下
- 求二值图像中,象素遍历算法
- 请问如何在没装vc的电脑上运行vc做的数据库程序?
- 怎样在画图时,使位图按路径方向划出来?简单一点说就是怎么样来划一条不规则的铁路(地图样式的铁路).
- 请大家关注这个网站 http://icnw.myrice.com
- 300分求助,為什麼我的 CHtmlView 類會不停的打開IE窗口??
- 我想用Office的组件的功能,在那里能找到资料?
- ActiveX控件(microsoft office Spreadsheet11)导出execel报错
- 急!已经使用FindWindowEx得到了NOTEPAD的句柄,怎样才能得到编辑框的文本字串
- opengl中有画一个一个点的函数吗
http://expert.csdn.net/Expert/topic/1738/1738628.xml?temp=.9618647
试试这么定义g_bThreadStop:
volatile bool g_bThreadStop;
可能你的现成的循环,每一步都需要比较长的时间,造成你的等待函数等不及了。问题2:
局部变量作用域的问题,那个局部变量已经不存在了,你不能通过传地址的方法。如果你只传递一个整数,那你应该采用传值的方法。============================================================================
提问题时标题要简明扼要地说明问题内容,切忌使用"急","求救"之类不能说明问题的标题
http://alphasun.betajin.com/ 给我发信息请附带原帖地址
http://www.betajin.com/alphasun/index.htm
DocWizard C++程序文档自动生成工具 | Wave OpenGL | HttpProxy | AjaxParser词法分析
当执行OnStop的时候,g_bThreadStop已经置为true了,
为什么FLSTrainThread并没有执行AfxMessageBox("成功结束线程!"),
而是进入if(dwRet==WAIT_TIMEOUT)内部?
答:因为线程现在没有结束,原因是全局的停止标记g_bThreadStop没有传递过去.
线程内部的那个g_bThreadStop只是真正的g_bThreadStop的一个拷贝,只有当线程正常结束时
才会改变成指定标志.解决该问题有两种方法1是用事件来同步,2是将g_bThreadStop声明为volatile 即可;
如果在加入(1)的代码,那么会先后执行MessageBox("非正常结束线程!");
AfxMessageBox("成功结束线程!"); 真是奇怪!
答:由于前面的原因,线程没有结束因而在指定的时间内不会成功返回(事实上线程还在正常运行),因而无秒之后,会返回超时标志.进而执行MessageBox("非正常结束线程!");,又因为你
TerminateThread了一把,强制线程退出,所以线程会执行到AfxMessageBox("成功结束线程!");
//====================================================================
问题2:
我想在CreateThread,调用FLSTrainThread的时候 想向FLSTrainThread传入一个整数
参数,我如下的做法为什么不可以?该怎么做?
int Index=100;
CreateThread(NULL,0,FLSTrainThread,&Index,0,&dwThreadID);
然后在
DWORD WINAPI FLSTrainThread(LPVOID lpParameter)
{
int index = *lpParameter; //为什么不可以?
...
} 答:原因是int Index=100;是个局部变量,且它是自动类型的变量,
也就是说没有固定的地址,因而解决这个问题的方法也有两个1是将Index声明为静态变量
2.是将Index变成类的成员变量,然后对其使用指针或引用.
(1)我已经按照你们的意思定义:volatile bool g_bThreadStop; 但是问题还是没有解决;(2)关于这个问题:我在程序里加入:MessageBox("非正常结束线程!");
则会执行 AfxMessageBox("成功结束线程!");
不加入就不执行AfxMessageBox("成功结束线程!");-----奇怪!
会不会是AfxMessageBox的问题,这样试试:
DWORD WINAPI FLSTrainThread(LPVOID lpParameter)
{
while(!g_bThreadStop)
{
...
}
//AfxMessageBox("成功结束线程!");把它放到if(dwRet==WAIT_OBJECT_0)里去
return 0;
}
DWORD dwRet=WaitForSingleObject(m_hThread,1000*5); //等待5秒
等待时间太短,而你的线程处理函数中的循环体执行时间大于5秒,改为
DWORD dwRet=WaitForSingleObject(m_hThread,INFINITE); 试一试在加入(1)的代码时,当执行完
// MessageBox("非正常结束线程!"); ------(1)之后,循环体由于g_bThreadStop=true退出,接着执行AfxMessageBox("成功结束线程!");不知道对不对,我不大懂多线程
DWORD dwRet=WaitForSingleObject(m_hThread,1000*5);换成
DWORD dwRet=WaitForSingleObject(m_hThread,INFINITE);以后,程序就进入了死等待状态,似乎g_bThreadStop对于停止线程FLSTrainThread(LPVOID lpParameter)没有起作用!另外:MessageBox("非正常结束线程!"); ------(1)处替换成
int j=0;
for(int i=0;i<10000;i++)
j++;
效果就不一样;前者会让子线程FLSTrainThread执行AfxMessageBox("成功结束线程!");
而后者就不能,奇怪...关于问题二:
问题已经解决。
BOOL volatile bThreadStop;
BOOL volatile bThreadStop; //全局变量
DWORD WINAPI FLSTrainThread(LPVOID lpParameter)
{
while(!g_bThreadStop)
{
//空
}
AfxMessageBox("子线程结束!");
return 0;
}// bThreadStop似乎没有受OnStop() 中 bThreadStop=true的影响...
[email protected]。记得用“紧急邮件”,这样速度快
MessageBox("非正常结束线程!")这句代码时,用时比较少的,这时还是
onstop函数在占用cpu,它会调用TerminateThread来终止线程,线程被
终止,当然就不会执行执行AfxMessageBox("成功结束线程!")啦。使用循
环体时,时间较长,可以保证onstop在执行TerminateThread之前时间片用
完,线程函数取得cpu的控制权就会执行AfxMessageBox("成功结束线程!")
啦。
对于第一个问题,也可以通过上面的操作系统的时间片轮转调度来解释。
多线程的问题和操作系统的调度很有关系。对于这个问题,可以把线程的
优先级设置的低一点,这样你加不加MessageBox("非正常结束线程!")结果
都不会改变的:只输出“非正常结束线程“。
换成这个就ok了。是不是AfxMessageBox要主线程来调用的?
关键是:我执行OnStop()
先执行 bThreadStop = true;然后
dwRet=WaitForSingleObject(m_hThread,INFINITE); //程序进入死等待...
为什么bThreadStop 这个标记没有被子线程FLSTrainThread中
while(!FLSTrainThread)
{
//
}
识别呢?
按照理解,子线程应该跳出循环才对啊。
int AFXAPI AfxMessageBox(LPCTSTR lpszText, UINT nType, UINT nIDHelp)
{
CWinApp* pApp = AfxGetApp();
if (pApp != NULL)
return pApp->DoMessageBox(lpszText, nType, nIDHelp);
else
return pApp->CWinApp::DoMessageBox(lpszText, nType, nIDHelp);
}
并不是bThreadStop 这个标记没有起作用,而是子线程调用AfxMessageBox之后程序陷入了死等状态。所以,换成::MessageBox(NULL, "STOP","成功结束线程!",MB_OK);
就可以了
看了你上面的原码,不清楚为什么AfxMessageBox会陷入死等状态状态,能解释一下吗?
另对于下面的代码:m_hThread = CreateThread(NULL,0,FLSTrainThread,NULL,0,&dwThreadID);
...
SuspendThread(m_hThread); // ---------(1)
ResumeThread(m_hThread); // ---------(2)bThreadStop = true;
dwRet=WaitForSingleObject(m_hThread,INFINITE); 如果程序只加入(1)程序陷入死等待
如果程序加入(1)、(2)程序正常结束主线程,是不是WaitForSingleObject
无法取到处于取到挂起状态的m_hThread?有什么变通的方法?
于是就造成了主线程等不及。
另外,我在你的工程里面加了一些TRACE语句,你将可以清楚的看到你的现成执行的流程。
(1)
正如hwonzor(闲人) 、alphapaopao(炮炮) 所指出来的,由于AfxMessageBox("子线程调用结束!")造成了所不期望的等待,于是就造成了主线程等不及。但是我并不是很理解为什么会这样(看了闲人提供的AfxMessageBox原码后还是不解)?能帮我解释一下吗?可以在以后避免类似的问题...(2)如题不修改AfxMessageBox这行;
我发现Stop主线程中:MessageBox("非正常结束线程!"); ------(1)
有了上面这个行代码,它会“激发”子线程中AfxMessageBox("成功结束线程!");
没有那话,哪怕执行10000行代码,也不会执行AfxMessageBox;
=========
尽管如论等多少时间,都是进入if(dwRet==WAIT_TIMEOUT) //超时
程序体中。