免责声明:我几天前在codereview上提出了这个问题,但没有得到答案。现在我将问题格式从审核请求更改为具体问题。
我正在开发一个带有以下设计的视频播放器:
主线程 - GUI线程(Qt SDK)。
第二线程 - 播放器线程,该线程接受来自GUI线程的命令以播放、快进、快退、停止等。现在,此线程在一个常量循环中运行,并使用互斥锁和等待条件与主线程命令保持同步。
我在这段代码中遇到了两个问题:
我感觉我的设计不完全正确:我同时使用了互斥锁和原子变量。我想知道是否只使用原子变量并仅在设置等待条件时使用锁。
当我运行“播放”命令并激活线程内部循环时,我遇到了不一致的错误(可能是由于播放命令尝试锁定线程已经锁定的互斥锁而导致竞争条件),所以我认为它阻止了主线程对共享变量的访问。
我已经从不需要的内容中剥离了代码,并且它通常是这样的:
void PlayerThread::drawThread()//thread method passed into new boost::thread
{
//some init goes here....
while(true)
{
boost::unique_lock<boost::mutex> lock(m_mutex);
m_event.wait(lock); //wait for event
if(!m_threadRun){
break; //exit the tread
}
///if we are in playback mode,play in a loop till interrupted:
if(m_isPlayMode == true){
while(m_frameIndex < m_totalFrames && m_isPlayMode){
//play
m_frameIndex ++;
}
m_isPlayMode = false;
}else{//we are in a single frame play mode:
if(m_cleanMode){ ///just clear the screen with a color
//clear the screen from the last frame
//wait for the new movie to get loaded:
m_event.wait(lock);
//load new movie......
}else{ //render a single frame:
//play single frame....
}
}
}
}
以下是上述类的成员函数,用于向线程循环发送命令:void PlayerThread::PlayForwardSlot(){
// boost::unique_lock<boost::mutex> lock(m_mutex);
if(m_cleanMode)return;
m_isPlayMode = false;
m_frameIndex++;
m_event.notify_one();
}
void PlayerThread::PlayBackwardSlot(){
// boost::unique_lock<boost::mutex> lock(m_mutex);
if(m_cleanMode)return;
m_isPlayMode = false;
m_frameIndex-- ;
if(m_frameIndex < 0){
m_frameIndex = 0;
}
m_event.notify_one();
}
void PlayerThread::PlaySlot(){
// boost::unique_lock<boost::mutex> lock(m_mutex);
if(m_cleanMode)return;
m_isPlayMode = true;
m_event.notify_one(); //tell thread to start playing.
}
所有的标志成员,例如m_cleanMode、m_isPlayMode和m_frameIndex都是原子类型:
std::atomic<int32_t> m_frameIndex;
std::atomic<bool> m_isPlayMode;
std::atomic<bool> m_cleanMode;
问题总结:
在使用原子操作时,我是否需要互斥锁?
我是否在线程的while循环中正确设置了等待位置?
有没有更好的设计建议?
更新:
虽然我得到了一个看起来正确的答案,但我确实不理解它。特别是伪代码部分,它谈到了服务,它完全不清楚如何工作。我想要一个更详细的答案。对于这样一个常见的问题,我只收到了一个有建设性的回答,这很奇怪。所以我重置了赏金。
QMutex
、QReadWriteLock
、QWaitCondition
。 - Super-intelligent Shade