Linux内核编程实验报告6
Linux内核分析实验报告
?
实验题目: 构造新内核同步机制实验
实验目的:设计同步原语模拟内核信号量。
硬件环境:内存1G以上
软件环境:Linux(Ubuntu) 2-6
实验步骤:
usr/src/linux-2.6.33.2/ipc/shm.c
一:实验原理简介:
信号量负责对共享缓冲区的互斥,主要实现的方法有信号量的声明(sys_sema_open),在特定信号量的等待(sys_sema_wait),将特定信号量上的等待进程唤醒(sys_sema_signal),删除特定信号量(sys_sema_close)。
声明信号量 :声明新的信号量结构,对本信号量等待队列初始化,本信号量信号灯数目初始化,然后将其放入信号量等待队列中。
在特定信号量的等待 :如果信号灯数目大于0,说明还有资源可以利用,将信号灯数目-1。否则,说明没有资源可用,将本进程置为WQ_FLAG_EXCLUSIVE,放入等待队列,调用schedule(),重新调度其他进程。Schedule()方法后是finish_wait() 方法,当进程被唤醒后,首先执行此方法。此方法将进程真正地从等待队列中弹出。
唤醒信号量上的等待进程 :进程即将从缓冲区离开,将信号灯的数目+1。此时,如果等待队列中还有等待进程(判断条件是信号灯的数目<0),则从等待队列中弹出一个进程,使其状态变为RUNNING,等待被调度。
删除特定信号量 :给出信号量的编号,判断等待队列上是否还有等待的进程,如果有的话,将所有的进程均从队列中弹出。然后从信号量的队列中删除编号是输入数字的信号量结构。
二:体结构:
typedef struct __sema{
int key;//本信号量编号
int number;//本信号量信号灯个数
wait_queue_head_t *p; // 系统等待队列首指针
struct __sema *next;//所有信号量以链形式串在一起,本属性指向下一信号量结构
}sema;
三:主要函数简介 :
系统函数
wake_up()
唤醒等待队列中所有没有设置WQ_FLAG_EXELUSIVE的节 点对应的进程,并且唤醒等待队列中第一个设置标记WQ_FLAG_EXELUSIVE的进程
Wake_up_all()
除了唤醒等待队列中所有没有设置WQ_FLAG_EXELUSIVE的节点对应的进程外,还唤醒所有设置了此标记位的进程。
prepare_to_wait(queue, &wait, flag);
将进程以设置的标志位放入等待队列中。
finish_wait(queue,&wait);
将进程从队列中弹出
2 自定义函数(位置:/usr/src/linux-2.6.33.2/ipc/shm.c)
sema * check_sema_key(int key,sema **prev)
作用:检查以key值为编号的信号量是否存在于当前的信号量链中
asmlinkage int sys_sema_open(int key,int number)
作用:如果key=0声明一个新的信号量(链表的插入),如果key!=0,返回key值。
asmlinkage int sys_sema_wait(int key)
作用: 如果信号灯数目大于0,说明还有资源可以利用,将信号灯数目-1。否则,说明没有资源可用,将本进程置为WQ_FLAG_EXCLUSIVE,放入等待队列,调用schedule(),重新调度其他进程。Schedule()方法后是finish_wait() 方法,当进程被唤醒后,首先执行此方法。此方法将进程真正地从等待队列中弹出。
4. asmlinkage int sys_sema_signal(int key)
作用:进程即将从缓冲区离开,将信号灯的数目+1。此时,如果等待队列中还有等待进程(判断条件是信号灯的数目<0),则从等待队列中弹出一个进程,使其状态变为RUNNING,等待被调度。
5. int wake_up_all_ones(int key)
作用:唤醒key编号信号量上所有的等待进程。
6. asmlinkage int sys_sema_close(int key)
作用:给出信号量的编号,判断等待队列上是否还有等待的进程,如果有的话,将所有的进程均从队列中弹出。然后从信号量的队列中删除编号是输入数字的信号量结构。
五:结果检测:
设定信号量的number值是2, 生成3个进程,三个进程争夺两个资源。为了使实验结果明显,进程每次执行时候,使