我正在使用 pthreads 编写一个多线程演示程序,其中一个线程将数据加载到 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'd 以不被多重包含。
我很感激任何人都可以提供的帮助!