首页 > 学院 > 开发设计 > 正文

Linux OS内核 作业二:多线程访问

2019-11-06 08:53:36
字体:
来源:转载
供稿:网友

实验题目:

http://gauss.ececs.uc.edu/Courses/c4029/labs/lab3.html

大致内容就是多个线程访问同一个变量,变量累加。然后记录变量在累加的过程中被访问的次数。(不知道有没有说清楚,方正是挺拗口的)。

未同步时的情况

#include <linux/kernel.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/workqueue.h>#include <linux/sched.h> //wake_up_PRocess() #include <linux/kthread.h> //kthread_create()、kthread_run() #include <linux/time.h>MODULE_LICENSE("GPL");static int NUM = 1000000;int arr[1000000] = {0};int stat[1000000] = {0};struct task_struct *t1;struct task_struct *t2;struct timeval start;struct timeval end;int idx = 0;int cs1 = 0 , cs2 = 0;//用来显示运行时间void show_runningtime(void){ unsigned long diff; diff = 1000000 * (end.tv_sec-start.tv_sec)+ end.tv_usec-start.tv_usec; printk(KERN_INFO "thedifference is %ld/n",diff); return 0;}//累加,并记录int incrementer(void *ptr) { printk(KERN_INFO "Consumer TID %d/n", (int)ptr); while (idx < 1000000) { arr[idx++] += 1; if ((int)ptr == 1) { cs1++; }else if ((int)ptr == 2) { cs2++; } schedule(); } return 0;}//加载内核模块时int init_module( void ) { do_gettimeofday(&start); int id1 = 1, id2 = 2; t1 = kthread_create(incrementer, (void*)id1, "inc1"); t2 = kthread_create(incrementer, (void*)id2, "inc2"); if (t1 && t2) { printk(KERN_INFO "Starting../n"); wake_up_process(t1); wake_up_process(t2); } else { printk(KERN_EMERG "Error/n"); } return 0;}//卸载内核模块时,对统计的信息进行显示void cleanup_module( void ) { int tmp; int i; for (i = 0; i < NUM; i++) { tmp = arr[i]; stat[tmp]++; } int j; for (j = 0; j < NUM; ++j) { if (stat[j] > 0) { printk(KERN_INFO "stat[%d]:%d /n",j,(stat[j])); } } printk(KERN_INFO "cs1:%d/tcs2:%d/tcs1+cs2=%d/t",cs1,cs2,cs1+cs2); do_gettimeofday(&end); show_runningtime(); return;}

注: 1. 关于显示运行时间的问题,可以参考我的另一篇博文:http://blog.csdn.net/u013806583/article/details/58127067 2. 关于如何编译、加载和卸载内核模块,可以参考《Linux OS内核 作业一》的方法:http://blog.csdn.net/u013806583/article/details/58604378

加锁同步后

#include <linux/kernel.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/workqueue.h>#include <linux/sched.h> //wake_up_process() #include <linux/kthread.h> //kthread_create()、kthread_run() #include <linux/semaphore.h> //信号量#include <linux/time.h> //计算运行时间MODULE_LICENSE("GPL");static int NUM = 1000000;int arr[1000000] = {0};int stat[1000000] = {0};struct task_struct *t1;struct task_struct *t2;//信号量,用于同步struct semaphore lock;struct timeval start;struct timeval end;int idx = 0;int cs1 = 0 , cs2 = 0;int incrementer(void *ptr) { printk(KERN_INFO "Consumer TID %d/n", (int)ptr); while (idx < 1000000) { //加锁 if(!down_interruptible(&lock)) { arr[idx++] += 1; } if ((int)ptr == 1) { cs1++; }else if ((int)ptr == 2) { cs2++; } //释放锁 up(&lock); schedule();}return 0;}void show_runningtime(void){ unsigned long diff; diff = 1000000 * (end.tv_sec-start.tv_sec)+ end.tv_usec-start.tv_usec; printk(KERN_INFO "thedifference is %ld/n",diff); return 0;}int init_module( void ) {// start timing do_gettimeofday(&start); int id1 = 1, id2 = 2; t1 = kthread_create(incrementer, (void*)id1, "inc1"); t2 = kthread_create(incrementer, (void*)id2, "inc2"); //初始化索 sema_init(&lock, 1); if (t1 && t2) { printk(KERN_INFO "Starting../n"); wake_up_process(t1); wake_up_process(t2); } else { printk(KERN_EMERG "Error/n"); } return 0;}void cleanup_module( void ) { int tmp; int i; for (i = 0; i < NUM; i++) { tmp = arr[i]; stat[tmp]++; } int j; for (j = 0; j < NUM; ++j) { if (stat[j] > 0) { printk(KERN_INFO "stat[%d]:%d /n",j,(stat[j])); } } printk(KERN_INFO "cs1:%d/tcs2:%d/tcs1+cs2=%d/t",cs1,cs2,cs1+cs2); do_gettimeofday(&end); show_runningtime(); return;}

观察运行结果:

未加锁同步: 多线程访问变量——未同步

加锁同步: 多线程访问变量——加锁同步


系列博客: 相信当你需要其中一个的时候,也一定需要剩下的两个 Linux OS内核 作业一:kthread和workqueue Linux OS内核 作业二:多线程访问 Linux OS内核 作业三:设备驱动与读写信号量


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表