最近在写一个我把它称为RemoteMedia的东西。其中,服务端程序要创建一个新的进程完成某些工作。而且,这个进程结束后,服务端还要通知客户端。
我所想到的方法是,创建这个进程后,保存进程的句柄值。为了及时获得进程的工作状况(是否退出、退出代码为多少)而又不阻塞服务端主线程的运行,我创建一个新的线程,并把这个句柄值作为线程回调函数的实参。按照自己初步想法写完后,满心欢喜去调试,结果出现了Access violation。
下面,请看这部分代码:
创建线程:
线程Routine:
错误很明显了吧!
因为我把一个栈上的对象作为线程回调函数的实参了,而我又没保证在线程结束之前这个对象是一直有效的,所以就出现了Access violation。
我所想到的方法是,创建这个进程后,保存进程的句柄值。为了及时获得进程的工作状况(是否退出、退出代码为多少)而又不阻塞服务端主线程的运行,我创建一个新的线程,并把这个句柄值作为线程回调函数的实参。按照自己初步想法写完后,满心欢喜去调试,结果出现了Access violation。
下面,请看这部分代码:
创建线程:
typedef struct _TidParms
{
CMKVMerge *pMkvmerge;
CRMSConnect *pSockConn;
} TidParms, *PTidParms;
void CMKVMerge::CreateMkvmergeStatChkTid()
{
// ...
TidParms parm;
parm.pMkvmerge = this;
parm.pSockConn = pSockConn;
m_hChkMkvmergeTid = _beginthreadex(..., CheckIfMkvmergeExit, &parm, ...);
// ...
}
线程Routine:
UINT __stdcall CMKVMerge::CheckIfMkvmergeExit(LPVOID pParam)
{
PTidParms pTidParm = (PTidParms)pParam;
::WaitForSingleObject(pTidParm->pMkvmerge->GetRunningProcHandle(),
INFINITE);
DWORD dwMkvmergeExitCode;
if (::GetExitCodeProcess(pTidParm->pMkvmerge->GetRunningProcHandle(), &dwMkvmergeExitCode))
{
if (0 == dwMkvmergeExitCode)
{
// 通知客户端
}
}
pTidParm->pMkvmerge->CloseRunningProcHandle();
return EXIT_SUCCESS;
}
错误很明显了吧!
因为我把一个栈上的对象作为线程回调函数的实参了,而我又没保证在线程结束之前这个对象是一直有效的,所以就出现了Access violation。