微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 esp32 arduino 上分离 std::thread 有时会阻塞,有时不会

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。