0

私はpthreadsを使用してマルチスレッドのデモプログラムを作成しています。このプログラムでは、1つのスレッドがデータをSTLキューにロードし、別のスレッドがそこから読み取ります。些細なことですね。残念ながら、キューにプッシュされたデータは消えつつあります。私はマルチスレッドに不慣れではなく、メモリ構造に慣れていません-しかし、これは私を困惑させます。

これらは、キュー自体とそれを保護するミューテックスの宣言です。これらは、クライアントコードに含まれるヘッダーにあります。

static std::queue<int32_t> messageQueue;
static pthread_mutex_t messageQueueLock; 

プログラムが起動すると、プロセス共有属性を使用してミューテックスが初期化されます。

pthread_mutexattr_t sharedAttr;
pthread_mutexattr_init(&sharedAttr);
pthread_mutexattr_setpshared(&sharedAttr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&messageQueueLock, &sharedAttr);

次に、「プロデューサー」スレッドと「コンシューマー」スレッドを起動し、それらに処理​​を実行させます。プロデューサースレッドは新しいアイテムをキューにプッシュしてからスリープ状態になります。キューに何かを追加する行は次のとおりです。

pthread_mutex_lock(&messageQueueLock);
messageQueue.push(message);
pthread_mutex_unlock(&messageQueueLock);

次にスリープし、コンシューマスレッドに引き継がせます。ただし、コンシューマスレッドがキュー内のアイテムをチェックすると、キューは魔法のように空になります。

gdbを使用してプログラムをステップスルーしました。以下は私の実行の出力です。プロデューサーがキューに何かを追加する場所を確認できます。キューのサイズを印刷してそこにあることを確認します。コンシューマースレッドへのコンテキストスイッチがあり、キューのサイズをもう一度印刷すると、空になります。見てみな:

(gdb) b main_ex.cpp:70
Breakpoint 1 at 0x100006a24: file main_ex.cpp, line 70.
(gdb) run
Starting program: a.out 
Reading symbols for shared libraries ++. done
Creating the mutex.
Producer thread starting up. 
PRODUCER: Creating a message to send.
PRODUCER: Adding the message to the queue.
[Switching to process 7432]

Breakpoint 1, yourProcess () at main_ex.cpp:70
70      pthread_mutex_lock(&messageQueueLock);
(gdb) n
71      messageQueue.push(message);
(gdb) p messageQueue.size()
$1 = 0
(gdb) n
72      pthread_mutex_unlock(&messageQueueLock);
(gdb) p messageQueue.size()
$2 = 1
(gdb) b consumer.cpp:81
Breakpoint 2 at 0x1000043f7: file consumer.cpp, line 81.
(gdb) c
Continuing.
PRODUCER: Sleep time!
[Switching to process 7432]

Breakpoint 2, Producer::processMessageQueue (this=0x1001000c0) at producer.cpp:81
81      pthread_mutex_lock(&messageQueueLock);
(gdb) n
83      if(messageQueue.empty()) {
(gdb) p messageQueue.size()
$3 = 0
(gdb) quit

だから、何が起こっているのか本当にわかりません。キューはクリティカルセクション(読み取り/書き込みの両方)でのみアクセスされ、キューは静的であり、ヘッダーはマルチインクルードされないようにif-defされます。

私は誰もが提供できるどんな助けにも感謝しています!

4

2 に答える 2

5

ヘッダーガードは、翻訳単位ごとに複数の包含から保護します。ただし、異なる翻訳単位はそれらを再含めます。

あなたの場合、彼らはそれぞれ独自の静的キューとミューテックスを取得しているようです。また、あなたが正しかったとしても考慮してください。ヘッダーを再度含めることなく、翻訳ユニットはキューとミューテックスが何であるかを知りません。宣言されていない識別子を使用しようとしています。

externが必要です。これは、実際にはstaticの反対です。

extern std::queue<int32_t> messageQueue;
extern pthread_mutex_t messageQueueLock;

次に、1つのユニットで、実際にそれらを定義します。

std::queue<int32_t> messageQueue;
pthread_mutex_t messageQueueLock;
于 2010-03-02T20:33:14.587 に答える
1

2つのスレッドが実際に同じキューにアクセスしているかどうかを確認する必要があります。そうでない場合は、静的キューを回避して、たとえばmain関数または便利な場所に作成してください。

于 2010-03-02T20:35:55.427 に答える