exit()函数_complete函数
上次讲解了一下add_wait_queue和add_wait_queue_exclusive两个函数,今天来讲另一个函数complete函数。
文件包含:
#include<linux/completion.h>
这个函数也是与内核进程调度相关的一个函数,因此它也位于kernel/sched/目录下,具体的实现在completion.c中,我们可以看看它的具体实现,这样对于我们更好的理解它的工作原理会很有帮助。
void complete(struct completion *x)
{unsigned long flags;spin_lock_irqsave(&x->wait.lock, flags);x->done++;__wake_up_locked(&x->wait, TASK_NORMAL, 1);spin_unlock_irqrestore(&x->wait.lock, flags);
}
我们可以看到,事实上complete函数调用了__wake_up_locked函数,只是在调用时采用了自旋锁并且关闭了中断。
函数功能:
complete函数用于唤醒等待队列中的睡眠进程,并记录等待队列中的唤醒次数,保存在字段done中。函数的参数是completion的一个结构体。
struct completion {unsigned int done;wait_queue_head_t wait;
};
completion结构体除了done字段之外,就是一个wait_queue_head_t的等待队列头。需要注意的是能唤醒的进程状态只能是TASK_INTERRUPTIBLE或者TASK_UNINTERRUPTIBLE,并且唤醒进程不是同步的,就是说只能唤醒一个然后再去唤醒另一个。
实例解析:
#include<linux/init.h>
#include<linux/module.h>
#include<linux/sched.h>
#include<linux/wait.h>
#include<linux/completion.h>
#include<linux/kthread.h>MODULE_LICENSE("GPL");
MODULE_AUTHOR("viz.xu, xujiweigo@163.com");static struct completion comple;
static struct task_struct* old_task;int my_test_function(void* args)
{printk("enter kernel function!n");printk("the current pid is %dn",current->pid);printk("the value of done of the comple:%dn",comple.done);printk("the state of the init thread is %ldn",old_task->state);complete(&comple);printk("the value of done of the comple:%dn",comple.done);printk("the state of the init thread is %ldn",old_task->state);return 0;
}int __init complete_init(void)
{printk("complete init! current->pid = %dn",current->pid);struct task_struct* new_task = NULL;old_task = current;new_task = kthread_create_on_node(my_test_function,NULL,-1,"comple");init_completion(&comple);wait_queue_entry_t data;init_waitqueue_entry(&data,current); wake_up_process(new_task);add_wait_queue(&(comple.wait),&data);long left_time = schedule_timeout_uninterruptible(1000);printk("the pid of new_task is %dn",new_task->pid);printk("the return result of the schedule_timeout_uninterruptible is %dn",left_time);return 0;
}void __exit complete_exit(void)
{printk("complete exit!n");
return;
}module_init(complete_init);
module_exit(complete_exit);
结果分析:
[ 2814.212263] complete init! current->pid = 40020
[ 2814.212397] enter kernel function!
[ 2814.212399] the current pid is 40021
[ 2814.212400] the value of done of the comple:0
[ 2814.212401] the state of the init thread is 2
[ 2814.212403] the value of done of the comple:1
[ 2814.212404] the state of the init thread is 0
[ 2814.212406] the pid of new_task is 40021
[ 2814.212407] the return result of the schedule_timeout_uninterruptible is 1000
从结果可以看出,子进程和父进程都执行了,并且子进程在父进程之前执行完毕。在my_test_ function中调用complete函数,父进程的状态发生了改变2->0,这是因为我们在init函数中调用了schedule_timeout_uninterruptible,使得父进程处于TASK_UNINTERRUPTIBLE状态。同是,调用complete函数之后,comple的done字段变为1,说明参数在等待队列被唤醒了一次。
exit()函数_complete函数相关推荐
- exit()和_exit()函数
进程就好比人一样有其生命,我们通过fork()函数来创建一个进程,那么我们又是如何来中止进程呢. 进程退出 1.在Linux中任何让一个进程退出 进程退出表示进程即将结束.在Linux中进程退出分为了 ...
- exit()函数学习
1.exit()函数介绍 函数名: exit() 所在头文件:stdlib.h 功 能: 关闭所有文件,终止正在执行的进程. 用法格式:void exit(int status) exit() 是电脑 ...
- Linux下Exit和_exit函数说明
exit和_exit函数都是用来终止进程的.当程序执行到exit或_exit时,系统无条件的停止剩下所有操作,清除包括PCB(进程控制块)在内的各种数据结构,并终止本进程的运行.但是,这两个函数是有区 ...
- 浅析exit()和atexit()函数
当内核使用一个一个exec函数执行c程序时,在调用main函数之前先调用一个特殊的启动例程,可执行程序需将此例程指定为程序的起始地址.启动例程从内核获取命令行参数和环境变量,然后为调用mian函数做好 ...
- C/C++中的exit()函数
C/C++中的exit()函数参数 exit()函数本身表示退出程序. 其中: exit(0):表示正常退出 exit(1):表示出错(或非正常)退出.当然,exit()的参数可以不只是1,也可以是其 ...
- exit和_exit函数
1.exit函数 1 #include <stdlib.h> 2 void exit(int status); 3 功能:退出当前进程 4 参数: 5 status:退出状态,由父进程通过 ...
- C语言通用工具库之exit()和atexit()函数
一.exit()和atexit()函数 exit()退出程序.在main()函数返回系统时将自动调用exit()函数. atexit()函数通过退出时注册被调用的函数提供这种功能,atexit()接受 ...
- c语言中exit函数_C ++中的exit()函数
c语言中exit函数 介绍 (Introduction) Today we'll learn about exit() in C++. We know we can break out of loop ...
- Linux多任务编程之五:exit()和_exit()函数(转)
来源:CSDN 作者:王文松 转自:Linux公社 ----------------------------------------------------------------------- ...
最新文章
- 防止在iOS设备中的Safari将数字识别为电话号码
- vue引用公用的头部和尾部文件。
- 采购订单模板_采购必备:如何搭建合规的采购流程
- mysql+nginx实现负载均衡
- java listen_java web-- listen
- (JSP)关于手机端(尤其是苹果手机)pdf文件无法打开的解决方案
- 知识管理在中国的发展趋势
- 计算机word制作成绩单,如何用word批量制作学生成绩单?
- java编译网络爬虫_自己动手做网络爬虫系列——1 | 学步园
- 虚拟机xp系统如何安装--win10专业版
- 我的世界java版和基岩版对比_我的世界:java版和基岩版你更看好哪个?未来的发展,谁会更好...
- 关于Touch的顺时针(CW),逆时针(CCW)旋转
- 关于order by的一些用法
- matlab软件及基础实验第8单元,《MATLAB统计分析与应用:40个案例分析》程序与数据(内含彩蛋)...
- Spring Boot + Spring Security + JWT + 微信小程序登录
- 三角形加几笔能变成什么_一个圆添上几笔能出来什么形状?例如:表,太阳,向日葵.-圆形加几笔得什么事物-数学-伍靖都同学...
- 运营商大数据的范围有多广
- android fake gps,Fake GPS Location
- 为什么现在深度学习才流行起来?
- SolidWorks toolbox齿轮再修改方法
热门文章
- 金融时间序列计算分析题1
- 网页html转为pdf,html页面转换成PDF文件
- 编程大神进阶,Python技巧小贴士
- 5个Python特性 越早知道越好的
- PyCharm中Scrapy的安装
- 如何得到发送邮件服务器地址(SMTP地址)
- LinQ To Object 基本用法
- C#开发ActiveX控件及制作CAB包
- “ORA-01034 - Oracle not available”和“ORA-27101 - shared memory realm does not exist”
- torch tensor去掉1维_浑身是刺的“维c之王”,有人管它叫“菠萝”,有人管它叫“梨”...