关于线程代码执行完了,但线程未退出,也未激发WaitForSingleObject的问题。

myiner 2011-12-07 10:08:18
RT,具体代码如下:

BOOL CMsgQueue::StopRevMsgThread(void)
{
if(m_hRevMsgThread)
{
//m_bThreadExit = TRUE;

CMsgQueue cMsgQueue(L"MsgQueueTest",1024,WriteMode);
// 往消息队列写数据
cMsgQueue.Write("__EXIT__",9);
cMsgQueue.Close();
// 等待线程成功退出
WaitForSingleObject(m_hRevMsgThread,INFINITE);
CloseHandle(m_hRevMsgThread);
m_hRevMsgThread = NULL;
m_hRevMsgThread = FALSE;
lpBuffer?free(lpBuffer),lpBuffer=0:0;
}
return ((m_hRevMsgThread==NULL) ? TRUE : FALSE);
}

DWORD WINAPI CMsgQueue::RevMsgThread(LPVOID pParam)
{
CMsgQueue *pMsgQueue=(CMsgQueue*)pParam;
DWORD dwReadNums=0;
while(!pMsgQueue->m_bThreadExit)
{
if(!pMsgQueue->m_hMsgQueue )
break;
// 从消息队列中读取一条消息(阻塞模式)
BOOL ret=pMsgQueue->Read(pMsgQueue->lpBuffer,pMsgQueue->m_dwQueueSize,&dwReadNums,INFINITE);
printf("Read ret=%d,dwReadNums=%d/n",ret,dwReadNums);
if(dwReadNums>0)
{
// 调用回调函数
if(strcmp("__EXIT__",(char*)pMsgQueue->lpBuffer)){
if(pMsgQueue->m_MsgCallBack)
pMsgQueue->m_MsgCallBack(pMsgQueue->lpBuffer,dwReadNums);
}else{
break;
}
}
}
printf("RevMsgThread exit...\r\n");
::ExitThread(0);
return 0;
}

debug窗口出来的内容:
[VPU DEC]Interlace : 0
[VPU DEC]Crop : 0,0,0,0
================================================
Read ret=1,dwReadNums=79/n[dll] PLAYER_THREAD_ATTACH
Read ret=1,dwReadNums=9/nRevMsgThread exit...

可以看到RevMsgThread exit...消息打印了,本应显示线程退出的提示的,并激发WaitForSingleObject继续运行,但这里线程一直没有退出。。
...全文
164 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
myiner 2011-12-12
  • 打赏
  • 举报
回复
谢谢楼上各位的解答,我用另种方法绕过了。
myiner 2011-12-12
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 moonchul 的回复:]

另外为什么要有以下代码,
CMsgQueue cMsgQueue(L"MsgQueueTest",1024,WriteMode);
// 往消息队列写数据
cMsgQueue.Write("__EXIT__",9);
cMsgQueue.Close();
直接用Write("__EXIT__",9)不可以吗……
[/Quote]
已创建的MsgQueue是读模式的,而无法写入。
myiner 2011-12-07
  • 打赏
  • 举报
回复
ExitThread(0)去掉也没有用。。
cMsgQueue只是用来通知线程退出,与param不是同一个东西。
我还是把全部的代码发出来。

#include <windows.h>
#include "EsMessage.h"

CMsgQueue::CMsgQueue()
{
m_hMsgQueue = NULL;
m_dwQueueSize = 0;
m_hRevMsgThread = NULL;
m_bThreadExit = FALSE;
m_MsgCallBack = NULL;
}

CMsgQueue::CMsgQueue(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode)
{
m_hMsgQueue = NULL;
m_dwQueueSize = 0;
m_hRevMsgThread = NULL;
m_bThreadExit = FALSE;
m_MsgCallBack = NULL;
Create(lpQueueName,dwSize,accessMode);
}

CMsgQueue::~CMsgQueue()
{
Close();
}

BOOL CMsgQueue::Create(LPCWSTR lpQueueName,DWORD dwSize,ACCESSMODE accessMode)
{
if(!m_hMsgQueue)
{
m_hRevMsgThread = NULL;
m_bThreadExit = FALSE;
m_MsgCallBack = NULL;
m_dwQueueSize = dwSize;
// 创建消息队列
MSGQUEUEOPTIONS options;
options.dwSize = sizeof(options);
options.dwFlags = MSGQUEUE_NOPRECOMMIT|MSGQUEUE_ALLOW_BROKEN;
options.dwMaxMessages = 0;
options.cbMaxMessage = dwSize;
options.bReadAccess = (accessMode==ReadMode) ? TRUE : FALSE;
m_hMsgQueue =::CreateMsgQueue(lpQueueName,&options);
}
return TRUE;
}

void CMsgQueue::Close(void)
{

// 注销回调函数
SetMsgCallBack(NULL,NULL);
if(m_hMsgQueue)
{
::CloseMsgQueue(m_hMsgQueue);
m_hMsgQueue = NULL;
}
}

BOOL CMsgQueue::Read(LPVOID lpBuffer,DWORD dwSize,LPDWORD lpNumberOfBytesRead,DWORD dwTimeout)
{
if(m_hMsgQueue == NULL || lpBuffer == NULL)
{
return FALSE;
}
DWORD dwFlag = 0;
// 从消息队列头部读出数据
if(!::ReadMsgQueue(m_hMsgQueue,lpBuffer,dwSize,lpNumberOfBytesRead,dwTimeout,&dwFlag))
{
return FALSE;
}
return TRUE;
}
BOOL CMsgQueue::Write(LPVOID lpBuffer,DWORD dwSize)
{
if(m_hMsgQueue == NULL || lpBuffer == NULL)
{
return FALSE;
}
// 向消息队列尾部写入数据
if(!::WriteMsgQueue(m_hMsgQueue,lpBuffer,dwSize,0,0))
{
return FALSE;
}
return TRUE;
}

BOOL CMsgQueue::SetMsgCallBack(MsgQueueCallBack pCallBackFun, PVOID pParam)
{
m_MsgCallBack = pCallBackFun;
if (m_MsgCallBack)
{
if (m_hRevMsgThread == NULL)
{
// 开启读取线程
return StartRevMsgThread();
}
}
else
{
if (m_hRevMsgThread)
{
// 关闭读取线程
return StopRevMsgThread();
}
}
return TRUE;
}

BOOL CMsgQueue::StartRevMsgThread(void)
{
if(m_hRevMsgThread == NULL)
{
// 创建读取消息线程
lpBuffer=(LPVOID)malloc(m_dwQueueSize);
m_hRevMsgThread=CreateThread(NULL, 0,CMsgQueue::RevMsgThread, this, 0, NULL);
}
return (m_hRevMsgThread ? TRUE : FALSE);
}

BOOL CMsgQueue::StopRevMsgThread(void)
{
if(m_hRevMsgThread)
{
//m_bThreadExit = TRUE;

CMsgQueue cMsgQueue(L"MsgQueueTest",1024,WriteMode);
// 往消息队列写数据
cMsgQueue.Write("__EXIT__",9);
cMsgQueue.Close();
// 等待线程成功退出
WaitForSingleObject(m_hRevMsgThread,INFINITE);
CloseHandle(m_hRevMsgThread);
m_hRevMsgThread = NULL;
lpBuffer?free(lpBuffer),lpBuffer=0:0;
}
return ((m_hRevMsgThread==NULL) ? TRUE : FALSE);
}

DWORD WINAPI CMsgQueue::RevMsgThread(LPVOID pParam)
{
CMsgQueue *pMsgQueue=(CMsgQueue*)pParam;
DWORD dwReadNums=0;
while(!pMsgQueue->m_bThreadExit)
{
if(!pMsgQueue->m_hMsgQueue )
break;
// 从消息队列中读取一条消息(阻塞模式)
BOOL ret=pMsgQueue->Read(pMsgQueue->lpBuffer,pMsgQueue->m_dwQueueSize,&dwReadNums,INFINITE);
printf("Read ret=%d,dwReadNums=%d/n",ret,dwReadNums);
if(dwReadNums>0)
{
// 调用回调函数
if(strcmp("__EXIT__",(char*)pMsgQueue->lpBuffer)){
if(pMsgQueue->m_MsgCallBack)
pMsgQueue->m_MsgCallBack(pMsgQueue->lpBuffer,dwReadNums);
}else{
break;
}
}
}
printf("RevMsgThread exit...\r\n");
return 0;
}
zhouzhipen 2011-12-07
  • 打赏
  • 举报
回复
把这个去掉::ExitThread(0);
ndy_w 2011-12-07
  • 打赏
  • 举报
回复
有点疑惑...m_hRevMsgThread对不?
你的cMsgQueue是个局部的东西,和线程函数里的param是一个东西吗?
龙行天下之Sky 2011-12-07
  • 打赏
  • 举报
回复
代码太多没有仔细看
你最好确保句柄在WaitForSingleObject时是有效的
Handle to the object. For a list of the object types whose handles can be specified, see the following Remarks section.
If this handle is closed while the wait is still pending, the function's behavior is undefined.
bingying19872008 2011-12-07
  • 打赏
  • 举报
回复
如果是win7下面的话 用WaitForSingleObject(m_hRevMsgThread,INFINITE);
这种方式来判断线程是否结束 是不行的.而xp是可以的...很早前我发现了,但是无解.
比如你用远程线程注入一个dll,然后等待远程线程执行完并关闭线程句柄....
会发现WaitForSingleObject 完全无效
moonchul 2011-12-07
  • 打赏
  • 举报
回复
另外为什么要有以下代码,
CMsgQueue cMsgQueue(L"MsgQueueTest",1024,WriteMode);
// 往消息队列写数据
cMsgQueue.Write("__EXIT__",9);
cMsgQueue.Close();
直接用Write("__EXIT__",9)不可以吗?
moonchul 2011-12-07
  • 打赏
  • 举报
回复
没有跑,不过建议把cMsgQueue.Close()和 WaitForSingleObject(m_hRevMsgThread,INFINITE)换下位置试一下

15,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧