本文摘自

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驱动之内核多线程(三)的更多相关文章

  1. linux驱动之内核多线程(二)

    本文摘自http://www.cnblogs.com/zhuyp1015/archive/2012/06/11/2545702.html 内核多线程是在项目中使用到,自己也不熟悉,遇到一个很囧的问题, ...

  2. linux驱动之内核多线程(一)

    本文摘自http://www.cnblogs.com/zhuyp1015/archive/2012/06/11/2545624.html Linux内核可以看作一个服务进程(管理软硬件资源,响应用户进 ...

  3. linux驱动之内核多线程(四)

    本文摘自 http://www.cnblogs.com/zhuyp1015/archive/2012/06/13/2548494.html 自己创建的内核线程,当把模块加载到内核之后,可以通过:ps ...

  4. Linux驱动之内核自带的S3C2440的LCD驱动分析

    先来看一下应用程序是怎么操作屏幕的:Linux是工作在保护模式下,所以用户态进程是无法象DOS那样使用显卡BIOS里提供的中断调用来实现直接写屏,Linux抽象出FrameBuffer这个设备来供用户 ...

  5. Linux驱动之内核加载模块过程分析

    Linux内核支持动态的加载模块运行:比如insmod first_drv.ko,这样就可以将模块加载到内核所在空间供应用程序调用.现在简单描述下insmod first_drv.ko的过程 1.in ...

  6. Linux 驱动之内核定时器

    1.定时器 之前说过两类跟时间相关的内核结构. 1.延时:通过忙等待或者睡眠机制实现延时. 2.tasklet和工作队列,通过某种机制使工作推后运行,但不知道运行的详细时间. 接下来要介绍的定时器,可 ...

  7. 【Linux驱动】内核等待队列

    在Linux中, 一个等待队列由一个"等待队列头"来管理,等待队列是双向链表结构. 应用场合:将等待同一资源的进程挂在同一个等待队列中. 数据结构 在include/linux/w ...

  8. Linux驱动:内核等待队列

    在Linux中, 一个等待队列由一个"等待队列头"来管理,等待队列是双向链表结构. 应用场合:将等待同一资源的进程挂在同一个等待队列中. 数据结构 在include/linux/w ...

  9. 嵌入式Linux驱动学习之路(三)u-boot配置分析

    u-boot配置流程分析 执行make tiny4412_config后,将会对u-boot进行一些列的配置,以便于后面的编译. 打开顶层目录下的Makefile,查找对于的规则tiny4412_co ...

随机推荐

  1. Go语言的跳跃表(SkipList)实现

    之所以会有这篇文章,是因为我在学习Go语言跳表代码实现的过程中,产生过一些困惑,但网上的大家都不喜欢写注释- - 我的代码注释一向是写的很全的,所以发出来供后来者学习参考. 本文假设你已经理解了跳表的 ...

  2. DQL_MySQL

    4.DQL(查询数据){SUPER 重点} 4.1DQL (Data Query Language : 数据查询语言) -所有的查询操作: Select 数据库中最核心的语言  create data ...

  3. css中的名词

    用到的单词 current 当前 hover 悬停 selected 挑选 disabled 禁用 focus 得到焦点 blur 失去焦点 checked 勾选 success 成功 error 出 ...

  4. python基础--深浅copy(重点)

    在此申明一下,博客参照了https://www.cnblogs.com/jin-xin/,自己做了部分的改动 深浅copy(重点) 先问问大家,什么是拷贝?拷贝是音译的词,其实他是从copy这个英文单 ...

  5. 跟老刘学运维day02~部署虚拟环境安装Linux系统(1)

    第1章 部署虚拟环境安装Linux系统 所谓“工欲善其事,必先利其器” 1.准备工具 VmwareWorkStation  15.5——虚拟机软件(必需) RedHatEnterpriseLinux ...

  6. Vue+ElementUI搭建一个后台管理框架

    参考 :https://www.cnblogs.com/taotaozhuanyong/p/11903750.html https://gitee.com/qianhongtang-share/vue ...

  7. 选择排序的实现以及如何编写测试 #CS61B-sp18-3.1

    Selection Sort的思想: 就是在一系列数字中先找到一个最小的放在所有数字的第一个位置上,然后再从余下的数字里面找最小个放在余下的数字里的第一个位置上. 例如: 在这段数据里面我们找到最小的 ...

  8. Python os.symlink() 方法

    概述 os.symlink() 方法用于创建一个软链接.高佣联盟 www.cgewang.com 语法 symlink()方法语法格式如下: os.symlink(src, dst) 参数 src - ...

  9. C++程序员容易走入性能优化误区!对此你怎么看呢?

    有些C++ 程序员,特别是只写C++ 没有写过 Python/PHP 等慢语言的程序员,容易对性能有心智负担,就像着了魔一样,每写3 行代码必有一行代码因为性能考虑而优化使得代码变形(复杂而晦涩). ...

  10. 虹软人脸识别—版本升级接口修改说明(C#)

    自虹软发布了免费.离线版本人脸识别SDK,在Github上陆续分享了各个版本对应的 C# Demo.因为公司项目一直在使用虹软的SDK,因此每当虹软官网有新版本发布,我都会进行了解,并结合Demo进行 ...