c++ - 竞争条件的棘手情况

标签 c++ multithreading c++11

我有一个音频播放类的竞争条件,每次我开始播放时我将 keepPlaying 设置为 true,而 false 当我停下来。

问题发生在我开始后立即停止(),并且 keepPlaying 标志设置为 false,然后重置为 true再次。

我可以延迟 stop(),但我认为这不是一个很好的解决方案。我是否应该使用条件变量让 stop() 等待直到 keepPlayingtrue

您通常会如何解决这个问题?

#include <iostream>
#include <thread>
using namespace std;


class AudioPlayer

{
    bool keepRunning;
    thread thread_play;

    public: 
    AudioPlayer(){ keepRunning = false; }
    ~AudioPlayer(){ stop(); }

    void play()
    {
        stop();
        // keepRunning = true; // A: this works OK
        thread_play = thread(&AudioPlayer::_play, this);
    }
    void stop()
    {
        keepRunning = false;
        if (thread_play.joinable()) thread_play.join();
    }
    void _play()
    {
        cout << "Playing: started\n";
        keepRunning = true; // B: this causes problem
        while(keepRunning)
        {
            this_thread::sleep_for(chrono::milliseconds(100)); 
        }
        cout << "Playing: stopped\n";
    }
};


int main()
{
    AudioPlayer ap;

    ap.play();
    ap.play();
    ap.play();

    return 0;
}

输出:

$ ./test
Playing: started
(pause indefinitely...)

最佳答案

这是我的建议,结合了下面的许多评论:

1) 将 keepRunning 标志与互斥锁进行简要同步,以便在前一个线程仍在更改状态时无法修改它。

2) 将标志更改为 atomic_bool,因为在不使用互斥锁时它也会被修改。

class AudioPlayer
{
    thread thread_play;

public:
    AudioPlayer(){ }
    ~AudioPlayer()
    {
        keepRunning = false;
        thread_play.join();

    }

    void play()
    {
        unique_lock<mutex> l(_mutex);
        keepRunning = false;
        if ( thread_play.joinable() )
            thread_play.join();
        keepRunning = true;
        thread_play = thread(&AudioPlayer::_play, this);
    }
    void stop()
    {
       unique_lock<mutex> l(_mutex);
       keepRunning = false;
    }
private:
    void _play()
    {
        cout << "Playing: started\n";
        while ( keepRunning == true )
        {
            this_thread::sleep_for(chrono::milliseconds(10));
        }
        cout << "Playing: stopped\n";
    }

    atomic_bool keepRunning { false };
    std::mutex _mutex;
};




int main()
{
    AudioPlayer ap;
    ap.play();
    ap.play();
    ap.play();
    this_thread::sleep_for(chrono::milliseconds(100));
    ap.stop();
    return 0;
}

关于c++ - 竞争条件的棘手情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43930221/

相关文章:

c++ - 指针 vector ,其元素用新的 : what happens when assigning a new value? 初始化

c++ - 如何在我的 CMakelists.txt 中链接 yaml-cpp?

c++ - 我可以只用事件、互斥量和信号量实现公平的 "wait on multiple events"吗?

java - 我的程序没有以执行器返回/结束

java - JavaFX线程中的“异步while循环”

c++ - 如何在 C++ 中使用带有映射的排序函数?

c++ - VS2015错误C2976

c++ - 无故对 glEnd 进行无效操作?

c++ - 鼠标移动增加代码执行速度 VB with C DLL

C++ cin 在点击回车后没有返回