我在dll里创建了一个线程,查资料知道不能在InitInstance()中创建,这个我弄好了,那么在主程序结束的时候,我怎么退出线程呢?比如说主程序点击右上的关闭按钮,我尝试在dll的ExitInstance()函数里设置一个Event,然后在线程中WaitForSingleObject(),然后在ExitInstance()中waitForSingleObject(myhThread,INFINITE) ,但是到waitForSingleObject(myhThread,INFINITE)程序始终在等待,估计是线程没有退出!!!相同的代码如果不用在dll中直接在一个exe中,是没有问题的!!!!这个问题困扰我好几天了,请各位高手指教,解决了马上给分,如果分不够另外开贴送分!!
{
UNREFERENCED_PARAMETER(lpReserved);
if (dwReason == DLL_PROCESS_ATTACH)
{
//dll attach,初始化
}
else if (dwReason == DLL_PROCESS_DETACH)
{
//ll detach
//可以试试让线程在这里退出
}
return 1;
}
while(m_bThreadRun)
{
....
}结束的方法:
m_bThreadRun = FALSE;
waitForSingleObject(myhThread,INFINITE);但是线程一定要保证是一直在循环,能检测到 m_bThreadRun = FALSE
to:aben456(相逢一笑) 我用向导生成的dll,已经看不到dllmain了,不过InitInstance和ExitInstance实际上调用的还是dllmain,问题依然
while(bRun){
.....
return 0;
}
是可以退出的,如果是
while(bRun){}
return 0;// 在这里放断点是可以到的,但是在往下跑就死锁了!就不行了,所以怀疑是我设置bRun=FALSE的位置不对,我是在dll的ExitInstance里设置的,因为我只又在这里才知道主程序要退出啊!!!
怎么结束,得取决于你的线程函数的写法
1.如果你的线程函数是没有循环,但是用了等待变量,那么你应该调用SetEvent唤醒它,
让线程自行结束就行
2.如果你的线程函数是有while(bContinue)这样的循环,你又在ExitInstance里
加入waitForSingleObject(myhThread,INFINITE)发现始终在等待,
这是因为你bContinue还是为true,或者你在线程函数中也有waitForSingleObject(h1)
这样的函数导致你的线程还在执行,那么你在ExitInstance里
直接设置它 bContinue=false ,若有等待变量的话,你还应该SetEvent(h1)
这样线程就自行结束了
我的线程是这样的UINT MyFunc( LPVOID pParam )
{
while(bRun) // bRun是全局变量
{
if(::WaitForSingleObject(pParma->m_hEvent,10) == WAIT_OBJECT_0)
{
...... // 我自己的操作
}
}
return 0; // 当在ExitInstance里设置bRun = false,函数在这里停住了,跟进去是
// AfxEndthread() 死锁了,实在是不明白问题原因
}// 下面是ExitInstance的代码
int CAlmMessApp::ExitInstance()
{
bRun = FALSE;
::WaitForSingleObject(p->m_hThread,INFINITE) // p = AfxBeginThread(DelayFunc,this);
}现在的问题是如果退出的代码不在ExitInstance里,是没有问题的,如果是上面的样子,怎在
*****线程******
for(;;)
{
DWORD dwRet=::WaitForSingleObject(m_ExitThread, MaxWaitTimes);
if (dwRet!=WAIT_OBJECT_0)
{
这里,你想干嘛就干嘛!
}
else
{
CloseHandle(m_ExitThread);
return 0;
}
}*******结束线程*********
Close()
{
if(m_ExitThread!=NULL)
VERIFY(SetEvent(m_ExitThread));//设置线程退出 Sleep(MaxWaitTimes);//等待一个线程运转周期,确保线程退出
}
bRun是在哪里定义?
又是在哪里修改的?
修改成功了没有?
我发现不能在dll的exitInstance函数里waitforsingleobject(p->m_hThread),这样会死锁,
其中, CWinthread *p = AfxBeginThead(Mythread,this);但是这样的用法在exe程序中是可以的,我现在折中的解决办法是另外设置一个Handle hquit,在thread退出时设置这个SetEvent(hquit),然后在
dll里的ExitInstance(){ ::WaitForSingleObject(hquit,INFINITE);}虽然问题解决了,但是原理没弄懂,希望有懂得高手来给解释一下,为什么一样的代码在dll里会死锁,在exe程序里就可以用!!!
btw:感觉在csdn里想问个答案真tmd难,在c++板块好点,你们说那么多星星都是怎么升上去的?
你应该在主程序(就是应用程序对象类)的函数ExitInstance里(而不是DLL类那个ExitInstance)
写上
bRun = FALSE;
::WaitForSingleObject(hThread,INFINITE);
不用Wait函数也可以,你可以换为sleep(100);防止主线程退得太快而让辅助线程来不及正常退出 你原来的写法就会出来你说的问题,这是因为你虽然是创建在DLL中定义的线程,但是创建的线程
还是在主程序空间,这样你退出时,主程序会强行销毁所有的资源,因此你不应该让DLL的ExitInstance去控件线程的退出
在主线程里设置bRun = FALSE是一样的道理,你的方法也是让主线程去设置某个控制变量让线程退出.
而不是把控制代码放到线程的ExitInstance()
CloseHandle(hNetHandle[i]);
UINT MyThread(void * pParam)
{
while(bRun)
{
...
}
::SetEvent(hquit);
return 0;
}dllApp::ExitInstance()
{
bRun = false;
::WaitForSingleObject(hquit,INFINITE);
...
}to:tigerfox(风之力:=Doing.浪淘沙)
我知道用TerminateThread()也可以结束线程,而且结束之后还应该delete thread;否则有泄漏,但是这种方法是mircosoft极力反对的,几乎所有的windows编程经典著作都说应该让线程自己结束,连afxEndThread这个函数都不推荐使用,作为一个星星,你就这样教导新人吗?
你把bRun = false; 放到dllApp::ExitInstance()里,注意仍然是主线程在执行这个函数。我已经在VC2003下写了测试过了,你这样做的结果虽然没有导致死锁,但是导致了主线程饿死现象,看看你写的代码
dllApp::ExitInstance()
{
bRun = false;
::WaitForSingleObject(hquit,INFINITE);
...
}
当主线程执行到bRun=false;之前就释放掉了,其原因是当程序退出时,主线程会先执行ExitProcess释放掉你的辅助线程,从而让你的MyThread线程非正常退出,也就是直接从while循环中退出,从而MyThread不能正常执行::SetEvent(hquit);这句代码再次唤醒主线程,导致让主线程永久睡眠了(饿死了)
不知道这样的解答你是否满意:)
在主程序的exitInstance里调用了::FreeLibrary(),应该是在::FreeLibrary()里面调用的dllApp::ExitInstance()吧?你的意思是说在::FreeLibrary()之后就先退出辅助线程然后在调用dllApp::ExitInstance这个函数是吗?
感谢你的解释,如果有什么可以继续说一下,晚上下班前就结贴了!分数都给你
bRun = false;时没有起作用,从而执行下一句::WaitForSingleObject(hquit,INFINITE)就阻塞了