-
错误案例1
-
错误案例2
int CDownloadPlugin::FirstProcessEvent(void* pEvent, void* target)
{
***
std::unique_lock <std::mutex> lck(g_lock);
{
***
}
repo_empty.notify_all();
***
}
DWORD WINAPI TestProc(LPVOID lpThreadParameter)
{
***
std::unique_lock <std::mutex> lck(g_lock);
while (g_queIEvent.empty())
{
repo_empty.wait(lck);
***
}
***
}
void CDownloadPlugin::run()
{
***
while (!this->isInterrupted()) {
m_Semaphore.Wait();
***
{
std::lock_guard<std::mutex> lk(m_mutex_filelist);
***
}
}
}
void CDownloadPlugin::UnInit()
{
//停止并等待线程结束
if (!this->isInterrupted())
{
this->interrupt();
}
CXdThread::join();
}
问题分析:
代码块-1:
问题代码:while (g_queIEvent.empty()), 注意此循环条件指的是线程终止条件(while循环跳出或者第一次没有进去表明此线程结束)
解决方法:①改为while (!this->isInterrupted()) ②改为while (!m_bStop) 要注意其他地方也要对应处理
代码块-2:
产生现象:进程停止卡死(因为子线程没有被正常停止,子线程正在等待互斥量释放——>>>变相的死锁问题)
问题代码:
//停止并等待线程结束
if (!this->isInterrupted())
{
this->interrupt();
}
解决方法:
this->interrupt();下一条语句加m_Semaphore.Signal(); 意思是在主线程停止的时候,设置完子线程终止标志,必须要额外通知子线程,否则子线程会死等信号状态。
-
修正方案
void CDownloadPlugin::run()
{
while (!m_bStop)
{
m_Semaphore.Wait();
{
std::lock_guard<std::mutex> lk(m_mutex_filelist);
if (XXX.empty()) // XXX代表消费的队列
{
continue;
}
}
***
}
int CDownloadPlugin::FirstProcessEvent(void* pEvent, void* target)
{
{
std::lock_guard<std::mutex> lk(m_mutex_filelist);
***
}
m_Semaphore.Signal();
}
void CDownloadPlugin::UnInit()
{
if (!m_bStop)
{
m_bStop = true;
m_Semaphore.Signal();
if (!CXdThread::isInterrupted())
{
CXdThread::interrupt();
}
CXdThread::join();
}
}
-
引申思考
总结:多线程程序需要关注的最核心的两个点:①线程退出标志②线程同步、互斥对象使用的代码位置一定要配合必要的辅助逻辑。 即可