c++ - esp32 arduino 上的分离 std::thread 有时会阻塞,有时不会
问题描述
我有一些代码在带有 arduino 内核的 ESP32 微控制器上运行,在setup()
函数中我希望有一些代码threadPressureCalib
在自己的线程中独立运行,所以我执行以下操作:
std::unique_ptr<std::thread> sensorCalib;
void setup()
{
sensorCalib.reset(new std::thread(threadPressureCalib));
std::thread* pc = sensorCalib.get();
pc->detach();
}
void loop()
{
...
}
然后,我定义threadPressureCalib()
如下:
void threadPressureCalib()
{
float pressure=0;
int count;
for(timestarted = millis();(millis()-timestarted) < 10000;)
{ // THIS ONE BLOCKS SETUP() AND LOOP() CODE EXECUTION
Serial.println("Doing things");
}
Serial.println("Doing other things");
for (count=1; count<= 5;count++)
{ //THIS ONE DOES NOT BLOCK SETUP() and LOOP()
float temp;
while(!timer2.Delay(2000)); //Not sure if this is blocking anything
do{
temp = adc_pressure();
}while(temp>104.0 || temp<70.0); //Catch errors
pressure += temp;
}
changeSetting(pressure/5.0);
return;
}
问题:在第一个 for 循环期间,setup()
函数的执行被停止(以及loop()
)
在第二个 for 循环期间,没有任何内容被停止,其余代码并行运行(如预期的那样)
为什么这段代码的前半部分会阻塞,而后半部分不会?
抱歉,如果问题含糊不清或问得不恰当,我的第一个问题就在这里。
注释中每个请求的 timer2 解释:
timer2 是一个自定义计时器类,timer2.Delay(TIMEOUT)
它存储第一次调用的时间戳,并false
在每次后续调用时返回,直到当前时间 = TIMEOUT,然后它返回true
并自行重置
NonBlockDelay timer2;
//time delay function (time in seconds to delay)
// Set iTimeout to current millis plus milliseconds to wait for
/**
* Called with milliseconds to delay.
* Return true if timer expired
*
*/
//Borrowed from someone on StackOverflow...
bool NonBlockDelay::Delay (unsigned long t)
{
if(TimingActive)
{
if((millis() >iTimeout)){
TimingActive = 0;
return(1);
}
return(0);
}
iTimeout = millis() + t;
TimingActive = 1;
return(0);
};
// returns true if timer expired
bool NonBlockDelay::Timeout (void)
{
if(TimingActive){
if((millis() >iTimeout)){
TimingActive = 0;
iTimeout = 0;
return(1);
}
}
return(false);
}
// Returns the current timeout value in milliseconds
unsigned long NonBlockDelay::Time(void)
{
return iTimeout;
}
解决方案
这里没有足够的信息告诉你答案,但似乎你不知道自己在做什么。
std::unique_ptr<std::thread> sensorCalib;
void setup(){
sensorCalib.reset(new std::thread(threadPressureCalib));
std::thread* pc = sensorCalib.get();
pc->detach();
}
因此,您在这里存储了一个新线程,该线程执行threadPressureCalib
然后立即将其分离。一旦线程被分离,实例std::thread
就不再管理它。那么,std::unique_ptr<std::thread> sensorCalib;
如果它实际上什么都不做,那么即使首先拥有又有什么意义呢?你是否意识到join
如果你想等到它完成,通常你需要线程?是不是你只是启动了一堆实例threadPressureCalib
——因为你可能没有验证它们是否完成了执行——并且它们相互干扰?
推荐阅读
- python - 在 C 扩展中从 Python 获取列表
- ember.js - EmberJS:从监视更改中排除文件夹
- javascript - Socket.io 仅适用于重新连接
- docker - 如何在 Gitlab-CI Runner 上下文中连接到 Apache?
- php - 错误号:1048 列 'btc' 不能为空
- json - .net 字典到 JSON 对象嵌套
- python - PIP 安装包失败,错误代码为 1
- ios - Fabric Crashlytics 显示“版本 xxx 需要调查”
- ansible - Ansible - 通过组名(键)上的正则表达式或 json_query(+JSME 函数)访问组变量(字典)中的主机(列表)
- python - 我们如何使用 Python 或 NodeJS 实现 JSON 到 PCAP?