问题描述
我在带有 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
的一堆实例(因为您可能没有验证它们是否已完成执行)并且它们相互干扰?