C++多线程程序中for循环条件用rvalue导致挂起的问题
多线程打印Zero/Even/Odd时的死锁问题
我正在完成一个编程任务:接收一个n值,使用三个线程分别打印zero、even和odd数字。例如当n=3时,预期输出为010203。但遇到了一个奇怪现象:当在for循环的条件判断中使用右值(比如(this->n)+1)时,程序会完全挂起无任何输出,且该现象仅出现在多线程程序中。
以下是完整代码:
#include <functional> // function #include <iostream> #include <mutex> // mutex #include <thread> // thread using namespace std; class ZeroEvenOdd { private: int n; mutex zero_mtx, even_mtx, odd_mtx; public: ZeroEvenOdd(int n) { this->n = n; zero_mtx.unlock(); even_mtx.lock(); odd_mtx.lock(); } // printNumber(x) outputs "x", where x is an integer. void zero(function<void(int)> printNumber) { for (int i = 1; i <= this->n; ++i) { zero_mtx.lock(); printNumber(0); if (i & 1) { // odd odd_mtx.unlock(); } else { // even even_mtx.unlock(); } } } void even(function<void(int)> printNumber) { for (int a = 2; a <= ((this->n) + 1); a += 2) { // NOTE: `(this->n) + 1` is an rvalue even_mtx.lock(); printNumber(a); zero_mtx.unlock(); } } void odd(function<void(int)> printNumber) { for (int b = 1; b <= ((this->n) + 1); b += 2) { // NOTE: `(this->n) + 1` is an rvalue odd_mtx.lock(); printNumber(b); zero_mtx.unlock(); } } }; // g++ 1116.cpp -std=c++11 -pthread -O0 && ./a.out int main() { printf("helloworld\n"); ZeroEvenOdd zod(3); auto printNumber = [](int x) { cout << x; }; thread threadA([&]() { zod.zero(printNumber); }); thread threadB([&]() { zod.even(printNumber); }); thread threadC([&]() { zod.odd(printNumber); }); threadA.join(); threadB.join(); threadC.join(); return 0; }
使用命令g++ 1116.cpp -std=c++11 -pthread -O0 && ./a.out编译运行后,程序会挂起无任何输出。
但如果将以下两行:
for (int a = 2; a <= ((this->n) + 1); a += 2) { // NOTE: `(this->n) + 1` is an rvalue for (int b = 1; b <= ((this->n) + 1); b += 2) { // NOTE: `(this->n) + 1` is an rvalue
修改为:
for (int a = 2; a <= ((this->n) + 0); a += 2) { for (int b = 1; b <= ((this->n) + 0); b += 2) {
程序就能完全符合预期运行。我尝试在单线程程序中复现该现象,但并未出现此问题,不确定该现象是否与多线程相关,现提供所有相关信息供排查。
更新:将笔误“左值”修正为“右值”。
内容的提问来源于stack exchange,提问作者Der Fänger im Roggen
相关产品推荐
相关产品推荐

