0

C++ でのスレッドと同時実行性について学ぶための簡単なプログラムを作成しようとしています。スレッドの同期を処理するためのキューといくつかの変数を実装する MyQueue という名前のテンプレート クラスを作成しました。

このクラスには、キューからアイテムを取得および配置する関数が 2 つと、キューを閉じてそれ以上のアクセスを回避する関数が 1 つだけあります。

プログラムは正常にコンパイルされますが、デバッグ時に次のエラーが発生します。

式: デキュー イテレータは参照解除できません

これは、get または put アイテムの場合、スレッドが何をしていても発生する可能性があります。

コードは次のとおりです。

template <class T> class MyQueue{
queue<T> myqueue;
int N;
bool open;
mutex m,m_open;
condition_variable cv,cv2;

public:
MyQueue(int size){
    N=size;
    open=true;
}

bool isOpen(){ 
    lock_guard<mutex> lg(m_open);
    return open;
}

void close(){
    lock_guard<mutex> lg(m_open);
    open=false;
    cv.notify_all();
    cv2.notify_all();
}

bool get(T &t){
    if(isOpen()==false)return false;
    if(myqueue.size()>0){
        {
            lock_guard<mutex> lg(m);
            t=myqueue.front();
            myqueue.pop();
            cv.notify_one(); 
        }
    }else{
        unique_lock<mutex> ul(m);
        cv2.wait(ul); 
        if(!isOpen()) return false;
        t=myqueue.front();
        myqueue.pop();
        cv.notify_one();
    }
    return true;
}



bool put(T t){
    if(!isOpen())return false;
    if(myqueue.size()<N){
        {
        lock_guard<mutex> lg(m); 
        myqueue.push(t);
        cv2.notify_one(); 
        }
    }else{
        unique_lock<mutex> ul(m);
        cv.wait(ul);
        if(!isOpen())return false;
        myqueue.push(t);
        cv2.notify_one();
    }
    return true;
}

};
4

1 に答える 1

0

get 関数と put 関数の両方で wait から wait_for に変更することでこれを解決しました。たとえば、次のように取得します。

if(!cv.wait_for(lock, std::chrono::milliseconds(2100), [this] { return !myQueue.empty();})) return false;

このようにして、スレッドは設定された時間だけ待機し、 myQueue.empty() の呼び出しには適切なロックは必要ありません(回答で示唆されているように)。

于 2013-04-16T13:10:06.137 に答える