我是靠谱客的博主 眼睛大银耳汤,最近开发中收集的这篇文章主要介绍1: linux 内核态下的多线程开发,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

方法1:通过信号量条件唤醒线程,首先可以在driver的probe函数中先创建并启动线程

1. wait_queue_head_t thread_wq

init_waitqueue_head(&thread_wq);  通常先要在init函数中初始化一个thread_wq,该thread_wq 用作到时候线程唤醒的信号量队列

2. 通常在probe或者在init等接口中就通过kthread_run接口去创建好线程并run,kthread_run函数不能再中断函数中调用,因为会有阻塞导致报错中断中 BUG: scheduling while atomic: swapper/0/0/0x00000102
struct task_struct *kthread;
kthread= kthread_run(thread_func, arg, "thread_func");
if(IS_ERR(kthread)){
     printk("error: Unable to start kernel thread.n");
}
3. 这个时候线程就开始run了,打印"the system is start"  但是阻塞到wait_event_interruptible_timeout中,等待 thread_flag == 1 且 wake_up_interruptible_all(&thread_wq), 才能打印thread running,通常在while循环中会考虑将thread_flag 清0。重新进入阻塞态,待重新唤醒。其中kthread_should_stop 接口是判定该进程是否退出,当进程退出时,本线程就会kthread_should_stop 会置上(在driver unregister时候),此处不用while(1) 是为了避免线程二次退出导致kernel crash的现象(在driver unregister前被kill了一次,driver unregister时候再stop一次)。
int thread_flag = 0;
int thread_func(void *arg){
    printk("#### the system is startn");
    while(!kthread_should_stop()){
        wait_event_interruptible_timeout(thread_wq, thread_flag == 1, 1),

        printk("#### thread runningn");
    }
    printk("#### the system is exitn");
    return 0;
}

4. ISR(中断服务程序)中,或者其它需要唤醒线程的地方,通过信号量。

copy_frame_run_flag = 1; 将thread_func中等待条件置上

wake_up_interruptible_all(&thread_wq) ;

5. 正常kthread_stop函数会在driver unregister时候去将线程stop掉,会保证进程退出时候 kthread_should_stop通常会置1

kthread_stop(kthread);
thread_flag = 0;

方法2:直接用调度的方法去让线程运行

1. struct task_struct *thread_task_p; 创建线程句柄

2. 通常在probe或者在init等接口中就通过kthread_create 接口去创建,但是不运行。

 thread_flag = 1;
 thread_task_p = kthread_create(thread_func, iav, "thread_func");
 printk("############## thread_flag = %dn",thread_flag );

3. 线程调度函数此时为就绪态了

int thread_func(void *arg){

      while(1){
        set_current_state(TASK_UNINTERRUPTIBLE); //线程处于等待状态,不可中断,等待wake_up_process 就可以起来。

        if (??){
            thread_flag = 0;
        } else {
            thread_flag = 1;
        }
        if(thread_flag ){
            printk("############## thread running n");
        } else {
            printk("####thread schedulen");
            schedule(); //将线程cpu调度出去
            set_current_state(TASK_RUNNING); //将线程设置为就绪态,等待cpu时间片调度。

            ssleep(5);
        }
    }
    return 0;
}

4. ISR(中断服务程序)中,或者其它需要唤醒线程的地方,去将线程唤醒。
    thread_flag = 1;
    wake_up_process(thread_task_p);
}

5. 正常kthread_stop函数会在driver unregister时候去将线程stop掉

kthread_stop(thread_task_p);
thread_flag = 0;

备注:如想对进程理解比较深入,可以参考这个文章

https://blog.csdn.net/weixin_34293911/article/details/86356832?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase

最后

以上就是眼睛大银耳汤为你收集整理的1: linux 内核态下的多线程开发的全部内容,希望文章能够帮你解决1: linux 内核态下的多线程开发所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部