none
c++11 用条件变量封装的安全队列 崩溃 RRS feed

  • 问题

  • 封装了一个很简单的条件变量弄的安全队列,

    创建了两个线程,一个压数据 一个取数据,

    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

    2018年1月26日 8:10

全部回复

  • 先点击button1  再点击button2  再点击确定 就会出现这种崩溃,或者程序卡主不退出,之所以这样弄,是两个线程,我先关闭一个线程,过1-2秒再关闭另外一个线程就会崩溃,或者卡主。如果button2 也加了 m_bOutStart = false; 就不会出现问题
    2018年1月26日 9:23
  • Hi 岁月流年,

    感谢在MSDN论坛发帖。

    >>先点击button1  再点击button2  再点击确定 就会出现这种崩溃,或者程序卡主不退出,之所以这样弄,是两个线程,我先关闭一个线程,过1-2秒再关闭另外一个线程就会崩溃,或者卡主。如果button2 也加了 m_bOutStart = false; 就不会出现问题.

    我的电脑上只有vs2017,下载你的工程升级到vs2015后,并没有出现崩溃。

    建议你升级到vs2017尝试一下,或者使用WindbgCRT等工具来查找具体原因。

    希望对你有所帮助。

    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
    2018年1月29日 7:52
  • 升级到vs2015 以后就不出现崩溃了,但是 线程退不出去了,会卡在那里,条件变量会一直wait
    2018年1月30日 10:22