Linux内核completion机制

我们可以在内核中创建很多线程了,但是这些线程之间怎么互动呢?
完成量机制,是linux系统提供的一种同步机制,用于一个执行单元等待另一个执行单元执行完某件事。(一个线程阻塞在那,等待另外一个线程去唤醒它)

struct completion{
    unsigned int done;
    wait_queue_head_t wait;
};

1、定义completion

struct completion my_completion;

2、初始化completion

init_completion(&my_completion);

3、等待completion


void wait_for_completion(struct completion *c);
void wait_for_completion_interruptible(struct completion *c);
void wait_for_completion_killable(struct completion *c);
unsigned long wait_for_completion_timeout(struct completion *c);

4、唤醒completion

void complete(strutc completion *c);    //唤醒一个等待的执行单元
void complete_all(strutc completion *c); //唤醒全部的等待执行单元

下面用一个列子说明一个线程换新另外一个线程的用法:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/completion.h>

MODULE_LICENSE("Dual BSD/GPL");
  
static struct task_struct *tsk_1;
static struct task_struct *tsk_2;
static struct completion wakeup;
  
static int wakeup_thread(void *data)
{
    int wakeup_time_count = 0;
    do {
        printk(KERN_INFO "wakeup_thread : %d times", ++wakeup_time_count);
        msleep(1000);
        if(wakeup_time_count == 10){
            /* wakeup completion */
            complete(&wakeup); 
        }
    }while(!kthread_should_stop());
    return wakeup_time_count;
}
 
static int completion_test_thread(void *data)
{
    int completion_time_count = 0;
    /* wait wakeup_thread completion */
    wait_for_completion(&wakeup);
    do{
        printk(KERN_INFO "completion_test_thread : %d times", ++completion_time_count);
        msleep(1000);
    }while(!kthread_should_stop());
    return completion_time_count;
}
  
static int kai_init(void)
{
    printk(KERN_INFO "completion test init!\n");
 
    /* init completion */
    init_completion(&wakeup);
 
    /* create wakeup_thread thread */
    tsk_1 = kthread_run(wakeup_thread,NULL,"wakeup_thread");
    if(IS_ERR(tsk_1)){
        printk(KERN_INFO "create wakeup_thread failed!\n");
        return 1;
    }
 
    /* create completion_test_thread thread */
    tsk_2 = kthread_run(completion_test_thread,NULL,"completion_test_thread");
    if(IS_ERR(tsk_2)){
        printk(KERN_INFO "create completion_test_thread thread failed!\n");
        return 1;
    }
 
    return 0;
 
}
  
static void kai_exit(void)
{
    printk(KERN_INFO "completion test  exit!\n");
    /*complete_all(&wakeup);*/
    if (!IS_ERR(tsk_2)){
        int ret_2 = kthread_stop(tsk_2);
        printk(KERN_INFO "completion_test_thread function has run %ds\n", ret_2);
    }
    if (!IS_ERR(tsk_1)){
        int ret_1 = kthread_stop(tsk_1);
        printk(KERN_INFO "wakeup_thread function has run %ds\n", ret_1);
    }
}
  
module_init(kai_init);
module_exit(kai_exit);

上面这个例子中 我们在kai_init中初始化了一个completion,并且创建了两个线程:wakeup_thread、completion_test_thread,
在completion_test_thread线程中我们调用了wait_for_completion 来将其阻塞住,及需要等待其他线程来唤醒该线程,在wakeup_thread线程中我们设置了每秒打印一个消息,并在第十秒的时候去唤醒completion_test_thread 中阻塞的completion

编译执行我们通过打印信息可以看到:
在这里插入图片描述
在completion_test_thread 线程未被唤醒前只能看到wakeup_thread线程的打印信息。此时completion_test_thread 线程被阻塞,而当wakeup_thread线程 调用了complete 唤醒了completion后,两个线程都可以由打印输出。
我们可以认为在wakeup_thread线程 中唤醒completion和completion_test_thread 线程被唤醒completion 是同步的。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值