linux驱动之内核多线程(三)
本文摘自
http://www.cnblogs.com/zhuyp1015/archive/2012/06/13/2548458.html
接上 一篇文章 ,这里介绍另一种线程间通信的方式:completion机制。Completion机制是线程间通信的一种轻量级机制:允许一个线程告诉另一个线程工作已经完成。为使用 completion, 需要包含头文件 <linux/completion.h>。
可以通过以下方式来创建一个 completion :
DECLARE_COMPLETION(my_completion);
或者, 动态创建和初始化:
struct completion my_completion;
init_completion(&my_completion);
等待 completion 是一个简单事来调用: void wait_for_completion(struct completion *c);
注意:这个函数进行一个不可打断的等待. 如果你的代码调用 wait_for_completion 并且
没有人完成这个任务, 结果会是一个不可杀死的进程。
completion 事件可能通过调用下列之一来发出:
void complete(struct completion *c);
void complete_all(struct completion *c);
如果多于一个线程在等待同一个 completion 事件, 这 2 个函数做法不同. complete 只
唤醒一个等待的线程, 而 complete_all 允许它们所有都继续。
下面来看使用completion机制的实现代码:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/wait.h>
#include <linux/completion.h>
MODULE_LICENSE("Dual BSD/GPL");
static struct completion comp;
static struct task_struct * _tsk;
static struct task_struct * _tsk1;
static int tc = ;
static int thread_function(void *data)
{
do {
printk(KERN_INFO "IN thread_function thread_function: %d times \n", tc);
wait_for_completion(&comp);
//tc = 0; ///在哪里都行
printk(KERN_INFO "has been woke up !\n");
}while(!kthread_should_stop());
return tc;
}
static int thread_function_1(void *data)
{
do {
printk(KERN_INFO "IN thread_function_1 thread_function: %d times\n", ++tc);
if(tc == )
{
complete(&comp);
tc = ;
}
msleep_interruptible();
}while(!kthread_should_stop());
return tc;
}
static int hello_init(void)
{
printk(KERN_INFO "Hello, world!\n");
init_completion(&comp);
_tsk = kthread_run(thread_function, NULL, "mythread");
if (IS_ERR(_tsk)) {
printk(KERN_INFO "first create kthread failed!\n");
}
else {
printk(KERN_INFO "first create ktrhead ok!\n");
}
_tsk1 = kthread_run(thread_function_1,NULL, "mythread2");
if (IS_ERR(_tsk1)) {
printk(KERN_INFO "second create kthread failed!\n");
}
else {
printk(KERN_INFO "second create ktrhead ok!\n");
}
return ;
}
static void hello_exit(void)
{
printk(KERN_INFO "Hello, exit!\n");
if (!IS_ERR(_tsk)){
int ret = kthread_stop(_tsk);
printk(KERN_INFO "First thread function has stopped ,return %d\n", ret);
}
if(!IS_ERR(_tsk1))
{
int ret = kthread_stop(_tsk1);
printk(KERN_INFO "Second thread function_1 has stopped ,return %d\n",ret);
}
}
module_init(hello_init);
module_exit(hello_exit);
运行结果:

linux驱动之内核多线程(三)的更多相关文章
- linux驱动之内核多线程(二)
本文摘自http://www.cnblogs.com/zhuyp1015/archive/2012/06/11/2545702.html 内核多线程是在项目中使用到,自己也不熟悉,遇到一个很囧的问题, ...
- linux驱动之内核多线程(一)
本文摘自http://www.cnblogs.com/zhuyp1015/archive/2012/06/11/2545624.html Linux内核可以看作一个服务进程(管理软硬件资源,响应用户进 ...
- linux驱动之内核多线程(四)
本文摘自 http://www.cnblogs.com/zhuyp1015/archive/2012/06/13/2548494.html 自己创建的内核线程,当把模块加载到内核之后,可以通过:ps ...
- Linux驱动之内核自带的S3C2440的LCD驱动分析
先来看一下应用程序是怎么操作屏幕的:Linux是工作在保护模式下,所以用户态进程是无法象DOS那样使用显卡BIOS里提供的中断调用来实现直接写屏,Linux抽象出FrameBuffer这个设备来供用户 ...
- Linux驱动之内核加载模块过程分析
Linux内核支持动态的加载模块运行:比如insmod first_drv.ko,这样就可以将模块加载到内核所在空间供应用程序调用.现在简单描述下insmod first_drv.ko的过程 1.in ...
- Linux 驱动之内核定时器
1.定时器 之前说过两类跟时间相关的内核结构. 1.延时:通过忙等待或者睡眠机制实现延时. 2.tasklet和工作队列,通过某种机制使工作推后运行,但不知道运行的详细时间. 接下来要介绍的定时器,可 ...
- 【Linux驱动】内核等待队列
在Linux中, 一个等待队列由一个"等待队列头"来管理,等待队列是双向链表结构. 应用场合:将等待同一资源的进程挂在同一个等待队列中. 数据结构 在include/linux/w ...
- Linux驱动:内核等待队列
在Linux中, 一个等待队列由一个"等待队列头"来管理,等待队列是双向链表结构. 应用场合:将等待同一资源的进程挂在同一个等待队列中. 数据结构 在include/linux/w ...
- 嵌入式Linux驱动学习之路(三)u-boot配置分析
u-boot配置流程分析 执行make tiny4412_config后,将会对u-boot进行一些列的配置,以便于后面的编译. 打开顶层目录下的Makefile,查找对于的规则tiny4412_co ...
随机推荐
- Flutter学习笔记(41)--自定义Dialog实现版本更新弹窗
如需转载,请注明出处:Flutter学习笔记(41)--自定义Dialog实现版本更新弹窗 功能点: 1.更新弹窗UI 2.强更与非强更且别控制 3.屏蔽物理返回键(因为强更的时候点击返回键,弹窗会消 ...
- zabbix修改默认密码
1.mysql -u root -p 2.desc users; 3.select userid,alias,passwd from users; 4.update users set passwd= ...
- 不想得手指关节炎?帮你提炼IDEA常用代码补全操作
一.常用的代码补全操作 1..for和.fori(for 循环遍历) 输入args.for回车(args是一个数组或集合类),则会生成for循环遍历: 输入args.fori回车,则会生成带有索引的f ...
- Canvas知识点补充
Canvas笔记 复习 初识canvas <canvas> 是 HTML5 新增的,一个可以使用脚本(通常为 JavaScript) 在其中绘制图像的 HTML 元素.它可以用来制作照片集 ...
- 小甲鱼零基础汇编语言学习笔记第五章之[BX]和loop指令
这一章主要介绍什么是[BX]以及loop(循环)指令怎么使用,loop和[BX]又怎么样相结合,段前缀又是什么鬼,以及如何使用段前缀. 1.[BX]的概念 [BX]和[0]类似 ...
- 性能分析(3)- 短时进程导致用户 CPU 使用率过高案例
性能分析小案例系列,可以通过下面链接查看哦 https://www.cnblogs.com/poloyy/category/1814570.html 系统架构背景 VM1:用作 Web 服务器,来模拟 ...
- Android JNI之动态注册
所谓动态注册,就是不用像静态注册那样按规则严格的命名native方法,而是在加载so库的时候完成这个从Java方法到native方法的匹配工作,而这个匹配工作,需要我们写native代码来完成.下面直 ...
- JQuery插件,轻量级表单模型验证(续 一)
之前的代码结构,不方便扩展多结构的模型验证 重新结构设计了一下验证模型核心 var validateForm = (function(model) { model.Key = "[data- ...
- 物联网实验Arduino(1)
回顾 我们使用的平台: Arduino 入门实验1 眨眼睛 /* Blink Turns an LED on for one second, then off for one second, repe ...
- Linux输出缓存你知道多大吗?
今天看到这个代码很简单,就是验证一下Linux系统的输出缓存大小.当 猜一下这个代码的输出: #include <stdio.h> #include <string.h> #i ...