Created
May 14, 2017 09:36
-
-
Save YaoC/3c97be3d70f262e5d48ae6e838c65338 to your computer and use it in GitHub Desktop.
Linux内核第四次作业
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @Author: ChengYao | |
* @Created time: 2017年5月14日 下午5:08 | |
* @Email: [email protected] | |
* @Description: Linux内核第四次作业 | |
* | |
*/ | |
/** | |
* [thread_writer description] | |
* 每0.1秒向链表插入一个节点 | |
* @param d [description] | |
* @return [description] | |
*/ | |
#include <linux/init.h> | |
#include <linux/module.h> | |
#include <linux/kernel.h> | |
#include <linux/slab.h> | |
#include <linux/rculist.h> | |
#include <linux/delay.h> | |
#include <linux/rcupdate.h> | |
#include <linux/sched.h> | |
#include <linux/kthread.h> | |
static struct task_struct *tskwriter; | |
static struct task_struct *tskreader1; | |
static struct task_struct *tskreader2; | |
struct ShareData | |
{ | |
int data; | |
struct list_head list; | |
}; | |
// 初始化头节点 | |
LIST_HEAD(head); | |
static int thread_writer(void *d) | |
{ | |
int count = 0; | |
while( !kthread_should_stop() ){ | |
// 控制打印日志的数量 | |
if(count<=50){ | |
// 为新节点分配内存 | |
struct ShareData *p = kmalloc(sizeof(*p),GFP_KERNEL); | |
p->data = count; | |
// 调用 list_add_rcu 将新节点加入链表 | |
list_add_rcu(&p->list,&head); | |
printk(KERN_EMERG "thread_writer: %d times\n", ++count); | |
} | |
// 休眠0.1秒 | |
msleep(100) | |
} | |
} | |
/** | |
* [thread_reader description] | |
* 每0.1秒打印一个节点 | |
* @param d [description] | |
*/ | |
static void thread_reader(void* d) | |
{ | |
int count = 0; | |
struct ShareData *p = NULL; | |
while( !kthread_should_stop() ){ | |
// 控制打印日志的数量 | |
if(count<=50){ | |
count++; | |
// rcu_read_lock 和 rcu_read_unlock 保持临界区 | |
rcu_read_lock(); | |
// list_for_each_entry_rcu 打印每个节点 | |
list_for_each_entry_rcu(p, &head,list){ | |
if(p){ | |
printk(KERN_EMERG "reader%d :data=:%d\n",current->pid,p->data); | |
} | |
} | |
rcu_read_unlock(); | |
} | |
// 休眠0.1秒 | |
msleep(100) | |
} | |
} | |
/** | |
* [start_module description] | |
* 在模块中创建一个写者线程和两个读者线程 | |
* 写者线程负责向链表中加入节点 | |
* 两个读者线程并发打印链表的所有节点 | |
*/ | |
static int __init start_module(void) | |
{ | |
// 创建写者线程 | |
tskwriter = kthread_run(thread_writer,NULL,"%s","writer"); | |
if (IS_ERR(tskwriter)) | |
{ | |
printk(KERN_EMERG "create tskwriter kthread failed !\n"); | |
}else{ | |
printk(KERN_EMERG "create tskwriter kthread ok !\n"); | |
} | |
// 创建第一个读者线程 | |
tskreader1 = kthread_run(thread_reader,NULL,"%s","reader1") | |
if (IS_ERR(tskreader1)) | |
{ | |
printk(KERN_EMERG "create tskreader1 kthread failed !\n"); | |
}else{ | |
printk(KERN_EMERG "create tskreader1 kthread ok !\n"); | |
} | |
// 创建第二个读者线程 | |
tskreader2 = kthread_run(thread_reader,NULL,"%s","reader2") | |
if (IS_ERR(tskreader2)) | |
{ | |
printk(KERN_EMERG "create tskreader2 kthread failed !\n"); | |
}else{ | |
printk(KERN_EMERG "create tskreader2 kthread ok !\n"); | |
} | |
return 0; | |
} | |
/** | |
* [end_module description] | |
* 退出模块,结束三个线程 | |
* @return [description] | |
*/ | |
static void __exit end_module(void) | |
{ | |
// | |
if(!IS_ERR(tskwriter)){ | |
kthread_stop(tskwriter); | |
printk(KERN_EMERG "thread tskwriter end\n"); | |
} | |
if(!IS_ERR(tskreader1)){ | |
kthread_stop(tskreader1); | |
printk(KERN_EMERG "thread tskreader1 end\n"); | |
} | |
if(!IS_ERR(tskreader2)){ | |
kthread_stop(tskreader2); | |
printk(KERN_EMERG "thread tskreader2 end\n"); | |
} | |
} | |
module_init(start_module); | |
module_exit(end_module); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment