为什么C++多线程程序在Windows中工作正常,在Linux中抛出“资源暂时不可用”?

m1m5dgzv  于 2023-05-22  发布在  Linux
关注(0)|答案(1)|浏览(124)

编辑:

根据Jonathan的评论,我试图创建一个独立的程序来重现这个问题。我无法重现该问题。
然后我切换到杰里米的评论,以确保我真的只打一次电话。原来,上游代码中有一个bug,当满足特定条件时,它会在循环中调用此代码。
我的第一个直觉是在线程创建之前有一个标志,以检查是否已经为给定的dayIndex创建了它。喜欢

if (threadSpawnedForEachDay[dayIndex]) {
        return;
    }

它处理了“资源暂时不可用”的问题,但是输出仍然有错误。我花了整整2天的时间来调试,因为我只能在30分钟后重现Linux发布版本中的行为。(* 它有递归逻辑,这个bug显示了100次调用的深度 *)。

我的原创文章

我用C++实现了一个简单的2线程逻辑

  • 一个线程在有限的时间内休眠,然后触发开关
  • 一个主线程,做一切。它周期性地检查开关,当它被翻转时,它知道要结束并优雅地退出

该程序在Windows中运行良好,但在Linux(Ubuntu 20.04)中,它最终会抛出一个系统错误:
“资源暂时不可用”。
我在Linux上试过htop,程序似乎无法控制地创建线程。是什么引起的?
这是我的header:

struct TimeHelper {
        std::atomic_bool *timerForEachDay;
        std::vector<std::chrono::seconds> startTimeVector;
        bool isTimeUp(int dayIndex);
        void setStartTime(int dayIndex);
        void timerThread(int dayIndex);
        TimeHelper();
        ~TimeHelper();
        void TimeHelperInitializer();
    };
    extern TimeHelper timer;

代码如下:* 为简洁起见,这里硬编码了一些值-我的实际代码使用配置文件 *

TimeHelper timer;

TimeHelper::TimeHelper() {
    timerForEachDay = NULL;
}

TimeHelper::~TimeHelper() {
    delete[] timerForEachDay;
}

//Separate initializer because the constructor is run before main
//This is only called once
void TimeHelper::TimeHelperInitializer() {
    timerForEachDay= new std::atomic_bool[2];
    for (int i = 0; i < 2; i++) {
        timerForEachDay[i]=false;
    }
    setStartTime(0); //setStartTime for other days is called elsewhere. It is only called once for each dayIndex at an appropriate time.
    return;
}

bool TimeHelper::isTimeUp(int dayIndex) {
    if (timerForEachDay[dayIndex] == true) return true;
    return false;
}

void TimeHelper::timerThread(int dayIndex) {
    std::this_thread::sleep_for(std::chrono::seconds(20));
    timerForEachDay[dayIndex] = true;
}

void TimeHelper::setStartTime(int dayIndex) {
    std::thread th(&TimeHelper::timerThread, this, dayIndex);
    th.detach();
    return;
}
jtw3ybtb

jtw3ybtb1#

结果发现上游代码中有一个错误,它重复调用setStartTime。
这个问题只出现在Linux中的原因是因为它是一个更快的操作系统。如果我让代码运行几天,Windows可能会有同样的体验。(* 如果有人好奇,程序会尝试在给定的时间内找到“最佳匹配”,但如果不可用,则会切换到寻找“足够好的匹配”*)。
感谢所有对我的问题发表评论的人。你的评论引导我走上了正确的方向。

相关问题