我目前有關於加入完成的std ::線程的問題。 我有一個簡單的消費類:加入完成std ::線程的死鎖
//Consumer.h
class Consumer
{
public:
//Ctor, Dtor
void Start();
void Release();
private:
void Run();
std::atomic<bool> m_terminate;
std::thread m_thread;
};
//Consumer.cpp
void Consumer::Start()
{
m_thread = std::thread(&EncodingProcessor::Run, this);
}
void Consumer::Release()
{
m_terminate = true;
if (m_thread.joinable())
m_thread.join(); //Here is the deadlock
}
void Consumer::Run()
{
while (true)
{
if (m_terminate)
break;
//This queue is blocking, it is fed with events from an encoder
PMVR::HardwareEncoder::EventWithId currentEvent = m_hwEncoder.GetEncodeEvent();
//If there is an event, again, wait for it, until the according frame is encoded
WaitForSingleObject(currentEvent.handle, INFINITE);
//Lock the encoded bitstream
PMVR::HardwareEncoder::BitStreamBufferInfo currentData =
m_hwEncoder.LockBitstream(currentEvent.id);
std::vector<unsigned char> tmp((unsigned char*)currentData.bitstreamPointer,
(unsigned char*)currentData.bitstreamPointer + currentData.bitstreamSize);
//And process it.
m_consumer->ProcessEncodingResult(currentData.bitstreamPointer, currentData.bitstreamSize);
m_hwEncoder.UnlockBitstream(currentEvent.id);
}
}
所以我可以啓動線程。線程做它應該做的。我可以結束該線程,因此Run()
內的循環被破壞。但是,如果我想加入這個線程,我會遇到一個僵局。
我們不是在談論main()
完成後發佈的線程結束。我可以Release()
它通過按鍵,但它不會工作的時間。
編輯: Start()
被稱爲是這樣的:
m_processorThread = new Consumer(*m_hwEncoder,
std::make_unique<FileSystemWriter>("file.h264"));
m_processorThread->Start();
Release()
被稱爲是這樣的:
if (glfwGetKey(handler->GetWindow(), GLFW_KEY_M) && !m_pressed)
{
m_pressed = true;
sessionAPI.Close();
}
sessionAPI.close()
只是調用Release()
。而已。
EDIT2:
對不起,你是對的。我發佈的代碼目前正在工作... 所以這個問題似乎在Run()
方法(更新,見上)。
所以我的誤解是,因爲在循環的頂部打破,它下面的整個東西不會被執行......看起來像GetEncodeEvent()
產生了死鎖。但爲什麼?在線程沒有等待什麼的地方,有沒有一種打破整個循環的優雅方式?此外,事件的提供者還活着,所以應該有通知...
你能告訴你如何調用'運行'和'釋放'? – NathanOliver
一個完整的[mcve]會有很大的幫助。 – AndyG
什麼是'EncodingProcessor :: Run()'在做什麼?這似乎是在另一個線程中運行的函數,因此我們需要查看該代碼以確定它爲什麼會死鎖。 – bnaecker