C++ boost planner_cond_.wait(lock) 报错1225

发布时间:2023年12月25日

1.如下程序段 boost unique_lock doesn’t own the mutex: Operation not permitted
问题:
其中makePlan是一个线程。这里的unlock导致错误这个报错 boost unique_lock doesn’t own the mutex: Operation not permitted

 bool navigation::makePlan(){  
      //cv::namedWindow("Dynamic Image", cv::WINDOW_AUTOSIZE); // 创建一个窗口
      global_cost_map_ = planner_costmap_ros_->getCostmap();
      costs_           = global_cost_map_->getCharMap(); 
      unsigned int cx  = global_cost_map_->getSizeInCellsX(), cy = global_cost_map_->getSizeInCellsY();//xwidth y height
      //int x[9]  = {748,1332,713,539,535,1424,1577,712,1007}; // x width  cx
      //int y[9]  = {cy-343,cy-312,cy-333,cy - 288,cy - 287,cy - 61,cy - 282,cy - 266,cy - 771};//y height cy
      int x[2] = {363,424};
      int y[2] = {cy - 694,cy - 1061};
      //int k =8;// 6;
      int k = 0;
      boost::unique_lock<boost::recursive_mutex> lock(planner_mutex_);
      while(1)
      { 
       // while(!runner_){
        //std::cout << "plan thread enter waiting status!" << std::endl;
        planner_cond_.wait(lock);
        lock.unlock();
         //   runner_ = true; 
       // }
        //std::cout << "starting planning..." << std::endl;
        if(state_ == PLANNING)  
        {
            global_cost_map_ = planner_costmap_ros_->getCostmap();
            costs_           = global_cost_map_->getCharMap(); 
            unsigned int cx  = global_cost_map_->getSizeInCellsX(), cy = global_cost_map_->getSizeInCellsY();

            convert_offset_ = 0.5;
            //lock.unlock();
            bool gotPlan = false;//navigation::makePlanner(start,goal,plan_result_cell_);


             //std::cout << "Planning Complete!" << std::endl;
        }
      }

    }

分析:


```cpp
boost::unique_lock<boost::recursive_mutex> lock(planner_mutex_);

while (1) {
    planner_cond_.wait(lock); // 等待条件变量的通知并解锁互斥量

    // 在条件变量的通知下被唤醒后,获取到互斥量的所有权
    bool gotPlan = false;
    
    // 执行计划的操作
    // ...
    // 设置gotPlan为true或false表示是否成功获得计划

    lock.unlock(); // 在计划完成后解锁互斥量

    lock.lock(); // 重新上锁互斥量
}

在这个例子中,在while循环开始之前,我们创建了一个boost::unique_lock对象并传入互斥量。然后,我们在循环体内调用planner_cond_.wait(lock)等待条件变量的通知,并在等待之前释放锁。当收到条件变量的通知时,unique_lock对象会自动重新获取互斥量的所有权,然后我们继续执行计划的操作。

在计划完成后,我们首先调用unlock()解锁互斥量,然后重新使用lock()重新上锁互斥量,以便在下一次循环开始时可以正确地等待新的条件变量通知。

通过这种方式,我们保证了唤醒的线程可以获得互斥量的所有权,并避免在没有所有权的情况下解锁互斥量导致的错误。


```cpp
 bool navigation::makePlan(){  
      //cv::namedWindow("Dynamic Image", cv::WINDOW_AUTOSIZE); // 创建一个窗口
      global_cost_map_ = planner_costmap_ros_->getCostmap();
      costs_           = global_cost_map_->getCharMap(); 
      unsigned int cx  = global_cost_map_->getSizeInCellsX(), cy = global_cost_map_->getSizeInCellsY();//xwidth y height
      //int x[9]  = {748,1332,713,539,535,1424,1577,712,1007}; // x width  cx
      //int y[9]  = {cy-343,cy-312,cy-333,cy - 288,cy - 287,cy - 61,cy - 282,cy - 266,cy - 771};//y height cy
      int x[2] = {363,424};
      int y[2] = {cy - 694,cy - 1061};
      //int k =8;// 6;
      int k = 0;
      boost::unique_lock<boost::recursive_mutex> lock(planner_mutex_);
      while(1)
      { 
       // while(!runner_){
        //std::cout << "plan thread enter waiting status!" << std::endl;
        planner_cond_.wait(lock);
        lock.unlock();
         //   runner_ = true; 
       // }
        //std::cout << "starting planning..." << std::endl;
        if(state_ == PLANNING)  
        {
            global_cost_map_ = planner_costmap_ros_->getCostmap();
            costs_           = global_cost_map_->getCharMap(); 
            unsigned int cx  = global_cost_map_->getSizeInCellsX(), cy = global_cost_map_->getSizeInCellsY();

            convert_offset_ = 0.5;
            //lock.unlock();
            bool gotPlan = false;//navigation::makePlanner(start,goal,plan_result_cell_);


             //std::cout << "Planning Complete!" << std::endl;
        }
       lock.lock();//循环结束要上锁
      }

    }

2. 上述线程占用CPU资源较大,如何处理?

可能是因为程序中的循环没有适当的等待时间,导致CPU不断地执行循环代码。为了降低CPU占用率,您可以在循环中添加适当的等待时间。

具体在循环添加如下等待时间:

  std::this_thread::sleep_for(std::chrono::milliseconds(100));



3.	C++ 报错 coredown如何解决?
     Aborted (core dumped)

首先设置“

 ulimit -c unlimited   //将coredown文件设置不限制存储空间

重新执行问题程序,camke 编译后在build文件下
在这里插入图片描述
发生core dump之后,使用gdb查看core文件的内容, 以定位文件中引发core dump的行,在在Linux下,查看core文件中的出错堆栈信息有二种方式,使用:gdb -c core.pid program_name或gdb [program_name] [core.pid]可以进入gdb模式:
在进入gdb后输入where并回车,就可以指出是在哪一行被Down掉,在哪个函数内,由谁调用等等。
在进入gdb后输入 bt,用bt命令查看backtrace以检查发生程序运行到哪里,来定位core dump的文件->行。

那我们的文件下运行

gdb -c core navigation

然后再输入

where

Reference

1. Linux遇到Aborted (core dumped)

文章来源:https://blog.csdn.net/qq_40464599/article/details/135194472
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。