【发布时间】:2015-04-10 10:02:37
【问题描述】:
我在使用互斥锁时遇到了一些问题,请考虑这个例子:
boost::mutex m;
void thread1_unstack(std::stack<std::string>& msg) {
while (true) {
if (msg.empty()) continue;
m.lock();
std::string msg_string = msg.top();
msg.pop();
std::cout << msg_string << std::endl;
m.unlock();
}
}
void thread2_stack(std::stack& msg) {
while (1) {
msg.push("very long message");
}
}
void wait_for_finish(std::stack& msg) {
while (!msg.empty()) sleep(1);
}
int main() {
std::stack<std::string> msg;
boost::thread t1 = boost::thread(boost::bind(&thread1_unstack, boost::ref(msg));
boost::thread t2 = boost::thread(boost::bind(&thread2_stack, boost::ref(msg));
wait_for_finish(msg);
t1.stop();
t2.stop();
}
所以问题在于函数wait_for_finish。该函数在调用 msg.pop() 时检测堆栈为空,因此线程会在之后立即停止,有时,消息 (std::cout) 不会完全打印在屏幕上。
所以我想为这 3 行“锁定”msg 变量:
std::string msg_string = msg.top();
msg.pop();
std::cout << msg_string << std::endl;
这样,wait_for_finish 在 std::cout 期间不会检测到堆栈为空。
我试图锁定一个 boost::mutex 并在最后解锁它,但没有任何改变。
所以不知道怎么解决
【问题讨论】:
-
你为什么不向我们展示无效的代码?
-
太长,保密协议,但这个例子很好地描述了我的问题
-
好吧,你的代码中有很多错误。例如,thread1 立即调用
msg.empty而不持有互斥体,线程2 调用push而不持有互斥体。所以你的代码到处都是坏的。您不能在一个线程中访问stack,而另一个线程可能正在修改它。 -
我添加了互斥锁。所以就我而言,wait_for_finish、thread1_unstack 和 mutex 是类的成员函数。 thread2_stack 是一个独立的函数
-
您需要使用互斥锁保护对
msg的每个访问。否则,您可能有一个线程访问堆栈,而另一个线程正在修改它,这是不允许的。如果这是一个重要程序中的现实世界问题,值得把事情做好,您可能需要创建(或找到)一个线程安全的可等待堆栈。
标签: c++ multithreading boost mutex