linux驱动之内核多线程(二)
本文摘自http://www.cnblogs.com/zhuyp1015/archive/2012/06/11/2545702.html
内核多线程是在项目中使用到,自己也不熟悉,遇到一个很囧的问题,导致cpu运行100%。
这是写的第一个内核线程程序,通过全局变量来实现两个内核线程之间的通信。但是这里遇到致命错误,就是:每当 wait_event_interruptible()被wake_up_interruptible 唤醒之后线程就进入死循环。后面发现是线程不会主动的自己调度,需要显式的通过schedule 或者 schedule_timeout()来调度。如果不加tc = 0 这一行,wait_event_intrruptible()就一直不会睡眠(参见前面的文章“等待队列”),不会被调度放弃CPU,因此进入死循环。这个过程可以通过分析wait_event_intrruptible()的源代码来看出。
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/wait.h>
MODULE_LICENSE("Dual BSD/GPL");
static struct task_struct * _tsk;
static struct task_struct * _tsk1;
static int tc = ;
static wait_queue_head_t log_wait_queue;
static int thread_function(void *data)
{
do {
printk(KERN_INFO "IN thread_function thread_function: %d times \n", tc);
wait_event_interruptible(log_wait_queue,tc == );
tc = ; ///必须加这一行,内核才会进行调度。内核线程不像应用程序会主动调度,我们需要显式的使用调度函数,想要在thread_function_1中去重置tc的值是不可能的,因为线程不会被调度,该线程会一直占用CPU
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 == && waitqueue_active(&log_wait_queue))
{
wake_up_interruptible(&log_wait_queue);
}
msleep_interruptible();
}while(!kthread_should_stop());
return tc;
}
static int hello_init(void)
{
printk(KERN_INFO "Hello, world!\n");
init_waitqueue_head(&log_wait_queue);
_tsk = kthread_run(thread_function, NULL, "mythread");
if (IS_ERR(_tsk)) { //需要使用IS_ERR()来判断线程是否有效,后面会有文章介绍IS_ERR()
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);
说明:这个程序的目的就是,使用一个线程(thread_function_1)通知另外一个线程(thread_function)某个条件(tc == 10)满足(比如接收线程收到10帧然后通知处理线程处理接收到的数据)
运行结果:
程序加载并运行(tc 的值等于10 之后 就会唤醒另外一个线程,之后tc又从10开始计数)

程序卸载(程序卸载其实还是要很注意的,很多程序在卸载的时候回出现各种问题后面文章会提到):

linux驱动之内核多线程(二)的更多相关文章
- 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驱动之内核多线程(三)
本文摘自 http://www.cnblogs.com/zhuyp1015/archive/2012/06/13/2548458.html 接上 一篇文章 ,这里介绍另一种线程间通信的方式:compl ...
- Linux驱动之内核自带的S3C2440的LCD驱动分析
先来看一下应用程序是怎么操作屏幕的:Linux是工作在保护模式下,所以用户态进程是无法象DOS那样使用显卡BIOS里提供的中断调用来实现直接写屏,Linux抽象出FrameBuffer这个设备来供用户 ...
- 嵌入式Linux驱动学习之路(二十四)Nor Flash驱动程序
Nor Flash和Nand Flash的不同: 类型 NOR Flash Nand Flash 接口 RAM-like,引脚多 引脚少 容量 小(1M.2M...) 大(512M.1G) 读 简 ...
- 嵌入式Linux驱动学习之路(二十三)NAND FLASH驱动程序
NAND FLASH是一个存储芯片. 在芯片上的DATA0-DATA7上既能传输数据也能传输地址. 当ALE为高电平时传输的是地址. 当CLE为高电平时传输的是命令. 当ALE和CLE都为低电平时传输 ...
- 嵌入式Linux驱动学习之路(二十)USB设备驱动
USB在接入系统的时候,以0的设备ID和主机通信,然后由主机为其分配新的ID. 在主机端,D+和D-都是下拉接地的.而设备端的D-接上拉时,表明此设备为高速设备:12M/s. D+接上拉时则是全速设备 ...
- Linux驱动之内核加载模块过程分析
Linux内核支持动态的加载模块运行:比如insmod first_drv.ko,这样就可以将模块加载到内核所在空间供应用程序调用.现在简单描述下insmod first_drv.ko的过程 1.in ...
- 小松之LINUX 驱动学习笔记(二)
这两天一直在看字符驱动那块,后来从网上找啦几个例子,自己编译啦下,安装啥的都挺正常,就是用测试程序测试的时候总出问题,现在找到一个能测试的代码,自己先看看和原来的那个代码有啥不同,后面会继续更新,说下 ...
随机推荐
- Spark 3.0 新特性 之 自适应查询与分区动态裁剪
Spark憋了一年半的大招后,发布了3.0版本,新特性主要与Spark SQL和Python相关.这也恰恰说明了大数据方向的两大核心:BI与AI.下面是本次发布的主要特性,包括性能.API.生态升级. ...
- 萌新学渗透系列之Hack The Box_Legacy
我将我的walkthrough过程用视频解说的形式记载 视频地址https://www.bilibili.com/video/BV1mZ4y1u7jG 一是因为看我视频的后来者应该都是刚入门的新手,视 ...
- Python JSON的基本使用
Python JSON的基本使用 一.json格式介绍 JSON(JavaScript Object Notation) 通用的数据类型,易于人阅读和编写. 跟字典有些类似,形式也是key-value ...
- Linux系统安装Samba共享服务器详解及安装配置
一.简介 Samba服务程序是一款基于SMB协议并由服务端和客户端组成的开源文件共享软件,实现了Linux和windows系统间的文件共享.SMB(Server Messages Block,信息服务 ...
- Eureka服务发现Discovery
功能: 对于注册进Eureka里面的微服务,可以通过服务发现来获得该服务的信息 修改controller 主启动类加@EnableDiscoveryClient注解
- Radiobutton基础语法
.Radiobutton(root 主窗口,text 文本内容,value 值(可以通过set 和 get 获取到的值),variable 变量修改原来的StringVar) self.radio_m ...
- 【JMicro】微服务开发及使用
JMicro是一个用Java语言实现的开源微服务全家桶, 源码地址:https://github.com/mynewworldyyl/jmicro, Demo地址:http://124.70.152. ...
- PHP stat() 函数
定义和用法 stat() 函数返回关于文件的信息. 该函数将返回一个包含下列元素的数组: [0] 或 [dev] - 设备编号 [1] 或 [ino] - inode 编号 [2] 或 [mode] ...
- [转]new一个对象的过程中发生了什么?
来自:沉默哥 | 公号 :程序员小乐 链接:cnblogs.com/JackPn/p/9386182.html Java在new一个对象的时候,会先查看对象所属的类有没有被加载到内存,如果没有的话,就 ...
- Java项目中经常遇到的一些异常情况
一. 1. java.lang.nullpointerexception 这个异常大家肯定都经常遇到,异常的解释是"程序遇上了空指针",简单地说就是调用了未经初始化的对象或者是不存 ...