子线程问题代码案例分析&引申思考

11 篇文章 0 订阅
  • 错误案例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();
	}
}
  • 引申思考

总结:多线程程序需要关注的最核心的两个点:①线程退出标志②线程同步、互斥对象使用的代码位置一定要配合必要的辅助逻辑。 即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值