c++11 条件变量使用问题

fakine 2018-01-27 05:43:38
void push(T new_value)
{
std::lock_guard<std::mutex> lk(m_mut);
m_data_queue.push_back(new_value);
m_data_cond.notify_all();
}

void wait_and_pop(T& value)
{
std::unique_lock<std::mutex> lk(m_mut);
m_data_cond.wait(lk, [this]{return !m_data_queue.empty();});
value = m_data_queue.front();
m_data_queue.pop_front();
}

两个线程,a线程压数据,b线程调用wait_and_pop取数据,现在问题是,如果a线程结束了,
那么程序退出的时候 b线程不退出,因为a线程结束了,没数据了,b线程会一直wait,这样b线程就不结束了,请问怎么解决这个问题
...全文
1063 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
yshuise 2019-07-13
  • 打赏
  • 举报
回复
楼主的理解是错误的。结束了,没有数据,它只会阻塞在那儿,并没有错。
mirro 2019-07-12
  • 打赏
  • 举报
回复
wait一个等待获取数据,一个等待退出。
其实我是猫爷 2019-06-25
  • 打赏
  • 举报
回复
void push(T new_value) { { std::lock_guard<std::mutex> lk(m_mut); m_data_queue.push_back(new_value); } m_data_cond.notify_all(); }
你的OPPA 2018-02-02
  • 打赏
  • 举报
回复
最low的方法就是在a线程中压入特定的数据(-1)后退出线程,b线程获取数据时判断值是否为(-1),是就直接退出
铥丟 2018-02-02
  • 打赏
  • 举报
回复
添加超时可以么
CT8100 2018-02-01
  • 打赏
  • 举报
回复
添加变量,做判断值。干脆直接暴力点用TerminateThread();记得释放资源哦...
mstlq 2018-02-01
  • 打赏
  • 举报
回复
引用 2 楼 fakine 的回复:
[quote=引用 1 楼 zilaishuichina 的回复:] 最简单的方法是加一个 a,b线程都能访问的 atomic<bool> 变量, 初始为false,a线程退出时置为true,b线程检测到变量变为true的时候退出
while (m_bOutStart) { std::unique_lock<std::mutex> lk(m_mut); m_data_cond.wait(lk, [this]{return !m_data_queue.empty();}); value = m_data_queue.front(); m_data_queue.pop_front(); std::this_thread::sleep_for(std::chrono::milliseconds(50)); } 问题是 a线程退出以后 ,就算设置m_bOutStart为false 首先会卡在wait这里,因为wait往下执行条件是 队列有数据,如果没数据就会卡在这里了。[/quote] push线程推出前,设置m_bOutStart为false,设置完立即调用m_data_cond.notify_all(); wait_and_pop中,m_data_cond.wait(lk, [this]{return !m_data_queue.empty();});改成
m_data_cond.wait(lk, [this]{return m_bOutStart || !m_data_queue.empty();}); 
if(m_data_queue.empty()) return;
zilaishuichina 2018-01-29
  • 打赏
  • 举报
回复
引用 2 楼 fakine 的回复:
[quote=引用 1 楼 zilaishuichina 的回复:] 最简单的方法是加一个 a,b线程都能访问的 atomic<bool> 变量, 初始为false,a线程退出时置为true,b线程检测到变量变为true的时候退出
while (m_bOutStart) { std::unique_lock<std::mutex> lk(m_mut); m_data_cond.wait(lk, [this]{return !m_data_queue.empty();}); value = m_data_queue.front(); m_data_queue.pop_front(); std::this_thread::sleep_for(std::chrono::milliseconds(50)); } 问题是 a线程退出以后 ,就算设置m_bOutStart为false 首先会卡在wait这里,因为wait往下执行条件是 队列有数据,如果没数据就会卡在这里了。[/quote] 为什么一定要wait呢

while (m_bOutStart)
{
	{
		std::lock_guard<std::mutex> lk(m_mut);
		if (!m_data_queue.empty())
		{
			value = m_data_queue.front();
			m_data_queue.pop_front();
		}
	}
	std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
//B线程退出
fakine 2018-01-29
  • 打赏
  • 举报
回复
没人解答吗?
fakine 2018-01-28
  • 打赏
  • 举报
回复
队列代码 template<typename T> class threadsafe_queue { public: threadsafe_queue(){}; threadsafe_queue(threadsafe_queue const& other) { std::lock_guard<std::mutex> lk(other.m_mut); m_data_queue = other.m_data_queue; } ~threadsafe_queue(){} void push(T new_value) { std::lock_guard<std::mutex> lk(m_mut); m_data_queue.push_back(new_value); m_data_cond.notify_one(); } void wait() { std::unique_lock<std::mutex> lk(m_mut); m_data_cond.wait(lk); } void pop(T& value) { std::lock_guard<std::mutex> lk(m_mut); value = m_data_queue.front(); m_data_queue.pop_front(); } void wait_and_pop(T& value) { std::unique_lock<std::mutex> lk(m_mut); m_data_cond.wait(lk, [this]{return !m_data_queue.empty();}); value = m_data_queue.front(); m_data_queue.pop_front(); } bool empty() const{ std::lock_guard<std::mutex> lk(m_mut); return m_data_queue.empty(); } void stopwait() { OutputDebugString(L"ttttt --- notify_one before"); std::lock_guard<std::mutex> lock(m_mut); m_data_cond.notify_one(); } private: mutable std::mutex m_mut; std::deque<T> m_data_queue; std::condition_variable m_data_cond; }; 实现代码 void CtestthreaddequeDlg::OnBnClickedButton1() { m_bstart = true; m_bOutStart = true; m_edit.SetWindowTextW(L""); m_edit.SetWindowTextW(L"start"); m_funtureIn = std::async(std::launch::async, [&](){ while (m_bstart) { static int i = 0; m_safeint->push(i); std::this_thread::sleep_for(std::chrono::milliseconds(50)); } OutputDebugString(L"ttttt --- m_funtureIn "); }); m_funtureOut = std::async(std::launch::async, [&](){ while (m_bOutStart) { OutputDebugString(L"ttttt --- m_funtureOut before pop "); int iOut = 0; m_safeint->wait_and_pop(iOut); OutputDebugString(L"ttttt --- m_funtureOut after pop"); std::this_thread::sleep_for(std::chrono::milliseconds(50)); } OutputDebugString(L"ttttt --- m_funtureOut ---------"); }); } void CtestthreaddequeDlg::OnBnClickedButton2() { m_edit.SetWindowTextW(L""); m_edit.SetWindowTextW(L"stop"); m_bstart = false; //m_bOutStart = false; } void CtestthreaddequeDlg::OnDestroy() { CDialogEx::OnDestroy(); m_bstart = false; m_bOutStart = false; m_safeint->stopwait(); delete m_safeint; m_funtureIn.valid(); m_funtureIn.wait(); m_funtureOut.valid(); m_funtureOut.wait(); int ii = 3; // TODO: 在此处添加消息处理程序代码 } 先执行button1 再执行button2 然后退出的时候 在destroy 就会卡在m_safeint->wait_and_pop(iOut); 这一句了
Saleayas 2018-01-27
  • 打赏
  • 举报
回复
我写程序的时候,都是简单化的,从来都是 wait 两个。 一个等待获取数据,一个等待退出。
fakine 2018-01-27
  • 打赏
  • 举报
回复
引用 3 楼 faihung 的回复:
这个跟加互斥锁一样
怎么解决?
faihung 2018-01-27
  • 打赏
  • 举报
回复
这个跟加互斥锁一样
fakine 2018-01-27
  • 打赏
  • 举报
回复
引用 1 楼 zilaishuichina 的回复:
最简单的方法是加一个 a,b线程都能访问的 atomic<bool> 变量, 初始为false,a线程退出时置为true,b线程检测到变量变为true的时候退出
while (m_bOutStart) { std::unique_lock<std::mutex> lk(m_mut); m_data_cond.wait(lk, [this]{return !m_data_queue.empty();}); value = m_data_queue.front(); m_data_queue.pop_front(); std::this_thread::sleep_for(std::chrono::milliseconds(50)); } 问题是 a线程退出以后 ,就算设置m_bOutStart为false 首先会卡在wait这里,因为wait往下执行条件是 队列有数据,如果没数据就会卡在这里了。
zilaishuichina 2018-01-27
  • 打赏
  • 举报
回复
最简单的方法是加一个 a,b线程都能访问的 atomic<bool> 变量, 初始为false,a线程退出时置为true,b线程检测到变量变为true的时候退出

65,189

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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