Linux内核---58.kthread与wait_event
2016-07-25 11:58
429 查看
1. 功能
init中起两个线程,
线程1等侍
线程2每隔1秒唤醒线程1
2. 代码
#include <linux/init.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/workqueue.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/wait.h>
static wait_queue_head_t mythread_wq;
struct task_struct *wait_thread_task;
struct task_struct *waken_thread_task;
static int wake_up_condition = 0;
static int my_wait_thread(void* data)
{
while(1)
{
wait_event_interruptible(mythread_wq, wake_up_condition);
wake_up_condition = 0;
printk("cong: %s:%d, wakeup \n",__FUNCTION__, __LINE__);
}
}
static int my_waken_thread(void* data)
{
while(1)
{
wake_up_condition = 1;
wake_up_interruptible(&mythread_wq);
msleep(1000);
printk("cong: %s:%d, waken\n",__FUNCTION__, __LINE__);
}
}
static int __init hello_init(void)
{
printk(KERN_ALERT "my first driver\n");
init_waitqueue_head(&mythread_wq);
wait_thread_task = kthread_create(my_wait_thread, NULL, "my_wait_thread");
if (IS_ERR(wait_thread_task)) {
return PTR_ERR(wait_thread_task);
}
wake_up_process(wait_thread_task);
waken_thread_task = kthread_create(my_waken_thread, NULL, "my_waken_thread");
if (IS_ERR(waken_thread_task)) {
return PTR_ERR(waken_thread_task);
}
wake_up_process(waken_thread_task);
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_ALERT "goodbye my first dirver\n");
return ;
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
3. 说明
a. 关于kthread
kthread_create创建的线程不会马上运行,需要调用wake_up_process()后线程开始执行
kthread_run 会创建并启动线程的函数
b. 关于wait_event
wait_event_interruptible()
wake_up_interruptible(&mythread_wq);
要想唤醒wait_event_interruptible()的进程,需要滿足两个条件:
a.condition为真的前提下 //刚开始以为只要这个condition为真就可以了,后来发现不行
b.还需要调用用wake_up
4.运行结果
[ 40.075829].(0)[1467:insmod]my
first driver
[ 40.094922].(0)[1468:my_wait_thread]cong: my_wait_thread:32, wakeup
[ 41.101196].(0)[1469:my_waken_thread]cong: my_waken_thread:43, waken
[ 41.102065].(1)[1468:my_wait_thread]cong: my_wait_thread:32, wakeup
[ 42.111162].(0)[1469:my_waken_thread]cong: my_waken_thread:43, waken
[ 42.112043].(1)[1468:my_wait_thread]cong: my_wait_thread:32, wakeup
[ 43.121312].(0)[1469:my_waken_thread]cong: my_waken_thread:43, waken
[ 43.122197].(1)[1468:my_wait_thread]cong: my_wait_thread:32, wakeup
[ 44.131133].(0)[1469:my_waken_thread]cong: my_waken_thread:43, waken
[ 44.132010].(1)[1468:my_wait_thread]cong: my_wait_thread:32, wakeup
[ 45.141168].(1)[1469:my_waken_thread]cong: my_waken_thread:43, waken
[ 45.142013].(0)[1468:my_wait_thread]cong: my_wait_thread:32, wakeup
[ 46.151078].(0)[1469:my_waken_thread]cong: my_waken_thread:43, waken
init中起两个线程,
线程1等侍
线程2每隔1秒唤醒线程1
2. 代码
#include <linux/init.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/workqueue.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/irqreturn.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/wait.h>
static wait_queue_head_t mythread_wq;
struct task_struct *wait_thread_task;
struct task_struct *waken_thread_task;
static int wake_up_condition = 0;
static int my_wait_thread(void* data)
{
while(1)
{
wait_event_interruptible(mythread_wq, wake_up_condition);
wake_up_condition = 0;
printk("cong: %s:%d, wakeup \n",__FUNCTION__, __LINE__);
}
}
static int my_waken_thread(void* data)
{
while(1)
{
wake_up_condition = 1;
wake_up_interruptible(&mythread_wq);
msleep(1000);
printk("cong: %s:%d, waken\n",__FUNCTION__, __LINE__);
}
}
static int __init hello_init(void)
{
printk(KERN_ALERT "my first driver\n");
init_waitqueue_head(&mythread_wq);
wait_thread_task = kthread_create(my_wait_thread, NULL, "my_wait_thread");
if (IS_ERR(wait_thread_task)) {
return PTR_ERR(wait_thread_task);
}
wake_up_process(wait_thread_task);
waken_thread_task = kthread_create(my_waken_thread, NULL, "my_waken_thread");
if (IS_ERR(waken_thread_task)) {
return PTR_ERR(waken_thread_task);
}
wake_up_process(waken_thread_task);
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_ALERT "goodbye my first dirver\n");
return ;
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
3. 说明
a. 关于kthread
kthread_create创建的线程不会马上运行,需要调用wake_up_process()后线程开始执行
kthread_run 会创建并启动线程的函数
b. 关于wait_event
wait_event_interruptible()
wake_up_interruptible(&mythread_wq);
要想唤醒wait_event_interruptible()的进程,需要滿足两个条件:
a.condition为真的前提下 //刚开始以为只要这个condition为真就可以了,后来发现不行
b.还需要调用用wake_up
4.运行结果
[ 40.075829].(0)[1467:insmod]my
first driver
[ 40.094922].(0)[1468:my_wait_thread]cong: my_wait_thread:32, wakeup
[ 41.101196].(0)[1469:my_waken_thread]cong: my_waken_thread:43, waken
[ 41.102065].(1)[1468:my_wait_thread]cong: my_wait_thread:32, wakeup
[ 42.111162].(0)[1469:my_waken_thread]cong: my_waken_thread:43, waken
[ 42.112043].(1)[1468:my_wait_thread]cong: my_wait_thread:32, wakeup
[ 43.121312].(0)[1469:my_waken_thread]cong: my_waken_thread:43, waken
[ 43.122197].(1)[1468:my_wait_thread]cong: my_wait_thread:32, wakeup
[ 44.131133].(0)[1469:my_waken_thread]cong: my_waken_thread:43, waken
[ 44.132010].(1)[1468:my_wait_thread]cong: my_wait_thread:32, wakeup
[ 45.141168].(1)[1469:my_waken_thread]cong: my_waken_thread:43, waken
[ 45.142013].(0)[1468:my_wait_thread]cong: my_wait_thread:32, wakeup
[ 46.151078].(0)[1469:my_waken_thread]cong: my_waken_thread:43, waken
相关文章推荐
- linux基础入门命令
- Linux进程通信(三)IPC信号
- linux之expect
- linux下获取当前屏幕分辨率和当前终端行列数的简单方法
- heartbeat安装
- centos6.7 64位环境下部署MySQL-5.7.13
- Linux查看CPU和内存使用情况【转】
- Linux基础命令
- Linux(centOS6.5)下SVN的安装、配置及开机启动
- linux centos 基本命令
- CentOS下采用Crontab实现PHP脚本定时任务
- Linux之用户身份的查看与切换(su+sudo)
- Linux core 文件介绍
- Linux下设置本地yum安装源
- R第一问 CentOS6.5 修改 /etc/sudoers 提示只读
- Linux源代码目录结构说明
- 菜鸟的Linux苦逼之路4 vim编辑器
- 从本机构建Linux应用程序VHD映像
- 从Azure上构建Linux应用程序映像
- 几个Linux命令