无人机项目中遇到的线程问题 以及 Linux 的多线程编程的高效开发经验

工作的第一个项目又是搞飞机......

老板要求把图像处理找红色灯管和蓝色灯管的程序分为两个线程分别分配给我的树莓派上两个核运行.

下面写下程序流程:

//全局的变量,主线程先从摄像头取一帧数据给他赋值
Mat pframe;
//创建四个staic(只能在该文件中使用的变量)变量,分别是linux中的互斥量和条件变量
static pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t mutex1=PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
static pthread_cond_t cond1=PTHREAD_COND_INITIALIZER;
//用于记录线程是否已经在等待的变量,用于解决Linux中signal后变量会复位的问题.
int thread_count=0;

//包裹pthread_mutex_unlock函数因为线程中pthread_cleanup_push(把在线程结束或者意外结束时需要执行的函数压到栈中)需要的执行函数的返回值和参数都为void*
void mutex_unlock(void * p){
    pthread_mutex_unlock((pthread_mutex_t *)p);
    return ;
}

//用于主线程与子线程之间参数传递的struct
struct arg_thread
{
    uchar red_L[3];
    uchar red_H[3];
    Point2i core;
    int theta;
    int tag=0;
};

//线程部分
void * red_light_thread(void * arg)
{    
    //首先指定线程运行的cpu
    //mask相当于一个CPU集
    cpu_set_t mask;
    //先清空mask
    CPU_ZERO(&mask);
    //把1号cpu设置给mask
    CPU_SET(1,&mask);
    //设置亲和度,就是设置cpu
    if (pthread_setaffinity_np(pthread_self(),sizeof(mask),&mask)<0)
        {
            fprintf(stderr,"set thread affinity failed\n");
        }
    //参数赋值
    arg_thread* arg_T = (arg_thread*)arg;
    //把unlock函数压入栈中,为了防止线程意外结束,而mutex还处于被锁住状态
    pthread_cleanup_push(&mutex_unlock, (void*)&mutex);
    .
    .
    //循环处理图片
    while(1){
       //锁住mutex后对thread_count和pframe进行处理
       pthread_mutex_lock(&mutex);
       //线程等待数加一
       thread_count++;
       //等待cond条件变量的触发,这个函数在没收到cond信号之前会把mutex释放掉(这个很重要这样可以确保线程已经进入等待状态后再对thread_cond进行操作)
       pthread_cond_wait(&cond,&mask);
       ....图像处理
       pthread_mutex_unlock(&mutex);
    }
    pthread_cleanup_pop(0);
    pthread_exit(0);
}


//主线程
int main(){
        //同样设置线程运行的cpu
    cpu_set_t m_mask;    
    CPU_ZERO(&m_mask);
    CPU_SET(2,&m_mask);
    if (pthread_setaffinity_np(pthread_self(),sizeof(m_mask),&m_mask)<0)
    {
        fprintf(stderr,"set thread affinity failed\n");
    }
    //开线程的id句柄
    pthread_t tid;
 ........
    //创建线程
    pthread_create(&tid, NULL,red_light_thread,(void *) &arg);
.......
    //循环,只要相机能够打开
     while (cap.isOpened()){
      //先锁住mutex然后对pframe赋值然后再释放
            if (pthread_mutex_lock(&mutex) == 0) {
            cout<<"main thread locked the mutex"<<endl;
            while (!cap.read(pframe)){
                cap.read(pframe);
                cout<<"reading camera...."<<endl;
            }

            pthread_mutex_unlock(&mutex);
        }
        //循环等待子线程是否进入等待状态,注意这里也需要把mutex锁住才执行锁不住就不执行.然后thread_count减一
         while(1){
            if(thread_count>0){
            pthread_mutex_lock(&mutex);
                cout<<"signaling"<<endl;
                pthread_cond_signal(&cond);
                thread_count--;
            pthread_mutex_unlock(&mutex);
            break;
            }
            }
 ........图像处理.
 //下面判断子线程是否一次运行完的的以后再写.
}


}







Linux 的多线程编程的高效开发经验


Linux 的多线程编程的高效开发经验Linux 的多线程编程的高效开发经验Linux 的多线程编程的高效开发经验
本文中我们针对 Linux 上多线
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值