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