You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 18:41:25