询问者
c++11 用条件变量封装的安全队列 崩溃

问题
-
封装了一个很简单的条件变量弄的安全队列,
创建了两个线程,一个压数据 一个取数据,
template<> class threadsafe_queue<sAudioData*> { 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(sAudioData* new_value) { std::lock_guard<std::mutex> lk(m_mut); m_data_queue.push_back(new_value); m_data_cv.notify_one(); } void wait_and_pop(sAudioData*& value) { std::unique_lock<std::mutex> lk(m_mut); m_data_cv.wait(lk, [this]{return !m_data_queue.empty(); }); value = m_data_queue.front(); m_data_queue.pop_front(); } std::shared_ptr<sAudioData*> wait_and_pop(){ std::unique_lock<std::mutex> lk(m_mut); m_data_cv.wait(lk, [this]{return !m_data_queue.empty(); }); std::shared_ptr<sAudioData*> res(std::make_shared<sAudioData*>(m_data_queue.front())); m_data_queue.front(); return res; } std::shared_ptr<sAudioData*> try_pop(){ std::unique_lock<std::mutex> lk(m_mut); if (m_data_queue.empty()) return std::shared_ptr<sAudioData*>(); std::shared_ptr<sAudioData*> res(std::make_shared<sAudioData*>(m_data_queue.front())); m_data_queue.pop_front(); return res; } bool empty() const{ std::lock_guard<std::mutex> lk(m_mut); return m_data_queue.empty(); } void clearData() // 清空语音数据队列 { std::lock_guard<std::mutex> lock(m_mut); while (!m_data_queue.empty()) { SAUDIODATA *pItem = m_data_queue.front(); m_data_queue.pop_front(); delete[]pItem->buffer; delete pItem; } } private: mutable std::mutex m_mut; std::deque<sAudioData*> m_data_queue; std::condition_variable m_data_cv; };
调用代码:
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) { sAudioData* data = new sAudioData; data->buffer = new char[1024]; memset(data->buffer, 0, 1024); m_safequeue->push(data); std::this_thread::sleep_for(std::chrono::milliseconds(50)); } }); m_funtureOut = std::async(std::launch::async, [&](){ while (m_bOutStart) { sAudioData* data = nullptr; m_safequeue->wait_and_pop(data); if (data != nullptr) { delete[] data->buffer; delete data; } std::this_thread::sleep_for(std::chrono::milliseconds(50)); } }); } void CtestthreaddequeDlg::OnBnClickedButton2() { m_edit.SetWindowTextW(L""); m_edit.SetWindowTextW(L"stop"); m_bstart = false; } void CtestthreaddequeDlg::OnDestroy() { CDialogEx::OnDestroy(); m_bstart = false; m_bOutStart = false; m_safequeue->clearData(); delete m_safequeue; m_funtureIn.valid(); m_funtureIn.wait(); m_funtureOut.valid(); m_funtureOut.wait(); int ii = 3; }
关闭的时候 到 m_funtureOut.wait()就崩溃,为什么呢?
工程代码在这个网盘里,工程vs2013
https://pan.baidu.com/s/1i6E4ZS5
全部回复
-
Hi 岁月流年,
感谢在MSDN论坛发帖。
>>先点击button1 再点击button2 再点击确定 就会出现这种崩溃,或者程序卡主不退出,之所以这样弄,是两个线程,我先关闭一个线程,过1-2秒再关闭另外一个线程就会崩溃,或者卡主。如果button2 也加了 m_bOutStart = false; 就不会出现问题.
我的电脑上只有vs2017,下载你的工程升级到vs2015后,并没有出现崩溃。
建议你升级到vs2017尝试一下,或者使用Windbg, CRT等工具来查找具体原因。
希望对你有所帮助。
Best Regards,
Baron Bi
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.- 已编辑 Baron Bi 2018年1月29日 7:52