linux 代码同步_屏障应用程序接口

linux 屏障应用程序接口


完成是一种代码同步机制,它比任何滥用锁/信号量和忙等待循环的行为都要好。当你想用yield()
或一些古怪的msleep(1)循环来允许其它代码继续运行时,你可能想用wait_for_completion*()
调用和completion()来代替。

1.1 用法

使用完成需要三个主要部分:

  • ‘struct completion’ 同步对象的初始化
  • 通过调用wait_for_completion()的一个变体来实现等待部分。
  • 通过调用complete()或complete_all()实现发信端。

1.2 屏障应用程序接口实战

1.2.1 vim complete.c
/*头文件引用*/
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/pid.h>
#include <linux/wait.h>
#include <linux/completion.h>
#include <linux/kthread.h>
MODULE_LICENSE("GPL");

/*全局变量定义*/
static struct completion comple; //用于保存completion的状态
struct task_struct * old_thread; //用于保存模块初始化进程
int my_function(void * argc)
{
    printk("in the kernel thread function! \n");
    printk("the current pid is:%d\n", current->pid); //显示当前进程的PID值
    printk("the value of done of the comple:%d\n", comple.done); //显示字段done的值
    printk("the state of the init function is :%ld\n", old_thread->state);
                          // 显示父进程的状态
    complete(&comple);    //调用函数唤醒进程,并更改done字段的值
    printk("the value of done of the comple:%d\n", comple.done);
                          // 显示函数调用之后字段done的值
    printk("the state of the init function is :%ld\n", old_thread->state);
                          // 显示父进程的状态
    printk("out the kernel thread function\n");
    return 0;
}
static int __init complete_init(void)
{
    char namefrm[] = "complete.c";
    struct task_struct * result;
    long left_time;
    printk("into complete_init.\n");
    old_thread = current;
    result=kthread_create_on_node(my_function, NULL, -1, namefrm); //创建新进程
    wake_up_process(result);
    init_completion(&comple);                  //初始化全局变量
    wait_for_completion(&comple);
    printk("the pid of result is :%d\n", result->pid);
                                               //显示函数kernel_thread( )的返回结果
    printk("the current pid is:%d\n", current->pid); //显示当前进程的PID值
    printk("out complete_init.\n");
    return 0;
}



static void __exit complete_exit(void)
        {
            printk("Goodbye complete\n");
        }


module_init(complete_init);
module_exit(complete_exit);

1.2.2 vim Makefile
obj-m:=complete.o

CURRENT_PAHT:=$(shell pwd)
LINUX_KERNEL:=$(shell uname -r)

LINUX_KERNEL_PATH:=/usr/src/linux-headers-$(LINUX_KERNEL)
all:

        make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PAHT) modules

clean:

        make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PAHT) clean

1.2.3 执行 make 的编译结果

在这里插入图片描述

1.2.4 执行程序
root@tan:/home/tan/test# dmesg  -c
root@tan:/home/tan/test# insmod  complete.ko
root@tan:/home/tan/test# dmesg
[  694.123908] into complete_init.
[  694.124129] in the kernel thread function!
[  694.124133] the current pid is:2828
[  694.124137] the value of done of the comple:0
[  694.124139] the state of the init function is :2
[  694.124149] the value of done of the comple:1
[  694.124151] the state of the init function is :0
[  694.124153] out the kernel thread function
[  694.124190] the pid of result is :2828
[  694.124197] the current pid is:2827
[  694.124199] out complete_init.

根据结果可以看见程序按照同步机制执行。

1.2.5 屏蔽 complete函数,即不发送完成信号

在这里插入图片描述

1.2.6 查看执行效果

在这里插入图片描述

可以看到程序处于等待完成信号中。

1.2.7 查看打印信息

在这里插入图片描述
可以看见创建的线程已经运行完成, 主线程没有输出等待完成信号后的输出。

神奇哇 😕

2. 总结

默认行为是不带超时的等待,并将任务标记为“UNINTERRUPTIBLE”状态。wait_for_completion()
及其变体只有在进程上下文中才是安全的(因为它们可以休眠),但在原子上下文、中断上下文、IRQ
被禁用或抢占被禁用的情况下是不安全的。

wait_for_completion() 变体有:
wait_for_completion_interruptible_timeout
wait_for_completion_interruptible
wait_for_completion_timeout
wait_for_completion_killable
wait_for_completion_killable_timeout
wait_for_completion_io
wait_for_completion_io_timeout
try_wait_for_completion

对完成发信号:
complete_all
completion_done
 
try_wait_for_completion()和completion_done()都可以在IRQ或原子上下文中安全调用。

进入linux大门可以看这个视屏:https://ke.qq.com/course/4032547?flowToken=1042701
学习还是得靠自己。❤️


2.1 技术参考

参考链接1: https://www.coolcou.com/linux-kernel/linux-process-scheduling-kernel-api/the-linux-kernel-complete.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值