C++ Concurrency In Actionの本から少し変更したコードがあります。 。 私は何をしようとしたが、その内のスレッドまたはスレッドのために私がすることができ、その後、ストアバックグラウンドジョブスレッドセーフなキューを実装することです キューは次のようになります。condition_variableとunique_lockを使って周期的クラッシュを引き起こす(GCC 4.7、OSX)
queue.h
#pragma once
#include "imgproc/i_queue.h"
#include <memory>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>
using namespace std;
namespace imgproc {
/* Blocking, concurrency-safe queue. The method that blocks is pop(),
* which makes the current thread wait until there is a value to pop
* from the queue.
*/
template <typename T>
struct ConcurrentQueue : public IQueueWriter<T>, public IQueueReader<T>
{
ConcurrentQueue() {}
ConcurrentQueue(const ConcurrentQueue &) = delete;
ConcurrentQueue & operator= (const ConcurrentQueue &) = delete;
/* Concurrency-safe push to queue.
*/
virtual void push(shared_ptr<T> val)
{
lock_guard<mutex> lk(_mutex);
_queue.push(val);
_cvar.notify_one();
}
/* Concurrency-safe check if queue empty.
*/
virtual const bool empty() const
{
lock_guard<mutex> lk(_mutex);
bool result(_queue.empty());
return result;
}
/* Waiting, concurrency-safe pop of value. If there are no values in
* the queue, then this method blocks the current thread until there
* are.
*/
virtual shared_ptr<T> pop()
{
unique_lock<mutex> lk(_mutex);
_cvar.wait(lk, [ this ] {return ! _queue.empty(); });
auto value(_queue.front());
_queue.pop();
return value;
}
private:
mutable mutex _mutex;
queue<shared_ptr<T>> _queue;
condition_variable _cvar;
};
}
私の理解では、1つのミューテックスがキューにアクセスしようとするすべての試みを保護すべきです。しかし、私は10で、約1時間のクラッシュテストを持っている:
テスト - その-クラッシュ-fragment.cpp
// Should have threads wait until there is a value to pop
TEST_F(ConcurrentQueueTest,
ShouldHaveThreadsWaitUntilThereIsAValueToPop) {
int val(-1);
thread t1([ this, &val ] {
for (uint i(0) ; i < 1000 ; ++i);
val = *_r_queue->pop();
});
for (uint i(0) ; i < 1000 ; ++ i) {
for (uint j(0) ; j < 1000 ; ++ j);
EXPECT_EQ(-1, val);
}
_w_queue->push(make_shared<int>(27));
t1.join();
EXPECT_EQ(27, val);
EXPECT_TRUE(_r_queue->empty());
}
を変数_r_queue
と_w_queue
ちょうどここで、同じConcurrentQueue
インスタンス上のインターフェイスです。
デバッグ情報を徹底的に取り除くのに費やした時間から、インスタンス変数が空の場合、常にpop()
への呼び出しがクラッシュの原因になっているように見えます。 誰でも私が間違っていることについてアドバイスをしてくれますか?私は同様の問題について助けを求めている他の投稿を見たことがありますが、条件変数が答えであると言われています。
これを解決するために、これをよりよくデバッグする方法についてのアドバイスはありますか? FWIW、私は手作業でsleep(1)
を持ってwhile
を実装しようとしましたが、それでも定期的にクラッシュしてしまいました。これはむしろ私の努力にもかかわらず競争状態になることを示唆しています。
ありがとうございました&すべての助けを借りて、私はそれをすべて気にする前にこれを理解しようとしました。
乾杯、 ダグ。
こんにちは - 詳細については、問題のコードを1つのメインファイルに取り出しました。このプログラムはコンパイルされると終了するはずですが、実際にはt.join()の最後の呼び出しでハングします。メインファイルはここにあります:https://gist.github.com/2396866 – biot023