1

Queueスレッドセーフにしようとしたクラスがあります。次の3つのメンバー変数があります。

    std::queue<T>   m_queue;
    pthread_mutex_t m_mutex;
    pthread_cond_t  m_condition;

プッシュアンドポップは次のように実装されます。

    template<class T> void Queue<T>::push(T value)
    {
        pthread_mutex_lock( &m_mutex );
        m_queue.push(value);
        if( !m_queue.empty() )
        {
            pthread_cond_signal( &m_condition );
        }
        pthread_mutex_unlock( &m_mutex );
    }

    template<class T> bool Queue<T>::pop(T& value, bool block)
    {
        bool rtn = false;
        pthread_mutex_lock( &m_mutex );
        if( block )
        {
            while( m_queue.empty() )
            {
                pthread_cond_wait( &m_condition, &m_mutex );
            }
        }
        if( !m_queue.empty() )
        {
            value = m_queue.front();
            m_queue.pop();  
            rtn = true;
        }
        pthread_mutex_unlock( &m_mutex );
        return rtn;
    }

残念ながら、このコードのせいである可能性のある問題が時折あります。つまり、2つのスレッドがあり、キューが空ではないのに、スレッド1が出てこない場合push()と、スレッド2が出ていない場合pop()blockパラメーターは)があります。true

他にも利用可能な実装があることは理解していますが、必要に応じてこのコードを修正してみたいと思います。誰か問題がありますか?

コンストラクターには適切な初期化があります。

    Queue()
    {
        pthread_mutex_init( &m_mutex, NULL );
        pthread_cond_init( &m_condition, NULL );
    }

そしてデストラクタ、対応する'destroy'が呼び出します。

4

4 に答える 4

1

Paul Rubelが述べたように、最初にミューテックスを初期化する必要があります。この時点で、初期化と最終化を処理するクラスでミューテックスをラップすることをお勧めします。例えば:

class mutex {
private:
    mutex(const mutex &m);
    mutex &operator=(const mutex &m);

    // OR inherit from boost::noncopyable
public:
    mutex() {
        pthread_mutex_init(&mut_, nullptr);
    }

    ~mutex() {
        pthread_mutex_destroy(&mut_);
    }

    pthread_mutex_t get() const { return mut_; }

private:
    pthread_mutex_t mut_;
};

注目すべきは、非常によく記述された同期クラスを含むBoost.Threadingライブラリです。

于 2012-12-19T22:46:32.907 に答える
0

使用する前にミューテックスを初期化する必要があります:pthread_mutex_init

//somewhere before push/pop
pthread_mutex_init(&m_mutex)
于 2012-12-19T22:34:51.927 に答える
0

これはあなたの問題とはまったく関係ありませんが、プッシュ機能を修正することができます:

template<class T> void Queue<T>::push(T value)
{
    pthread_mutex_lock( &m_mutex );
    if( m_queue.empty() )
    {
        m_queue.push(value);
        pthread_cond_signal( &m_condition );
    }
    else
    {
        m_queue.push(value);
    }
    pthread_mutex_unlock( &m_mutex );
}
于 2012-12-19T23:27:30.697 に答える
0

ARMのビルドをテストするときに問題が発生したことに気づきました。解決策は、pthreadsライブラリを更新することでした。更新されたpthreadを使用すると、すべてが正常に実行されます。

于 2013-01-07T16:00:26.413 に答える