我目前正在開發一個使用Qt進行原始視頻數據回放的多線程應用程序。有三個工作線程。一個是Reader線程,一個是處理器線程,另一個是視頻輸出線程。讀取器線程將原始數據讀入緩衝區,然後處理器將處理原始數據並將可顯示的數據放入幀FIFO中。陷入循環等待狀態。需要幫助退出
我的原始數據緩衝區實現爲一個哈希表,這意味着每個幀索引將有其相應的原始數據。一旦處理器完成處理原始數據一個特定幀,它將從原始數據緩衝區中刪除原始數據,以便讀取器可以在數據返回到之前讀取的幀後將數據讀入緩衝區。
我現在執行暫停功能時出現問題。我想要做的是當視頻暫停時,處理器和閱讀器應該退出,並且視頻輸出線程將在fifo中顯示一個相同的幀。我現在可以正確退出處理器線程。讀者似乎陷入了一個循環的等待狀況。
下面是我的讀者線程的一些代碼。
void ReaderThread::run()
{
forever
{
//inputState_ is internal state of the reader
if (inputState_ == stop)
// return from run() if state is stop
return;
//dataBuffer is a pointer to raw data buffer object
//This grab the mutex lock of the raw data buffer
dataBuffer->lock()
//frameIndex is counter for frame
if (dataBuffer->contains(frameIndex_))
{
//mutex_ is a member variable of type QMutex
mutex_.lock();
//Wait for the data to be removed.
dataBuffer->waitForWritable();
mutex_.unlock();
}
dataBuffer->unlock();
// Read data to raw frame buffer
uchar rawDataPointer = readRawData();
dataBuffer->lock();
//insert the frame number and corresponding pointer into the hash table
dataBuffer->insert(frameIndex, rawDataPointer);
//wake up processor.
dataBuffer->wakeForReadable()
dataBuffer->unlock();
mutex_.lock();
if (inputState_ == play)
frameIndex++;
mutex_.unlock();
}
}
void ReaderThread::stop()
{
mutex_.lock();
inputState_ = stop;
//Wake up the reader if the reader is waiting
dataBuffer->wakeAllWritable();
mutex_.unlock();
// Wait for run() to return.
QThread::wait();
}
處理器線程的實現方式類似。我一開始就停止了處理器,並且成功了。當我想從run()返回時,我從主線程調用ReaderThread :: stop()。但是我陷入了一個循環的等待狀態,如果讀者線程在緩衝區等待寫入,它永遠不會解鎖這個讀者線程的mutex_。因此,停止將總是阻止,程序只是掛起。我試圖在dataBuffer-> waitForWritable()之前不鎖定mutex_,但是,在調用dataBuffer-> wakeAllWritable()後,讀者線程將等待可寫權限。
任何人都可以提出一種方法來解決這個問題?我一直在努力想弄清楚如何擺脫這種循環等待的情況,但並沒有完全解決,因爲我對線程化編程還很陌生。
不應該在調用wakeAllWritable()之前鎖定dataBuffer嗎?這樣你就可以從waitForWritable和wakeForWritable中刪除_mutex.lock。現在讓我知道它是如何發展的。 –
@Franco,這是有道理的。當我回到辦公室時,我會試試看。謝謝。 – Scrathis