进程同步与信号量、信号量临界区保护、信号量代码实现

生产者-消费者实例

在这里插入图片描述
生产者发现 counter == BUFFER_SIZE 生产者等待(阻塞)
消费者发现 counter == 0 消费者等待(阻塞)

存在问题:

在这里插入图片描述
只用counter做判断,在图中情况下会导致P2不会被唤醒。
应该需要另一量(信号量)考虑记录有多少进程阻塞等信息,并进行判断。

信号量

在这里插入图片描述
在这里插入图片描述
sem < 0表示 sem 有多个进程在等待
sem > 0 表示有空闲
在这里插入图片描述
B,有2个资源可以使用

信号量的定义

在这里插入图片描述
queue代表阻塞队列

V()的模型:

V(semaphore s)
{
	s.value++;
	if(s.value <= 0)
	{
		wakeup(s.queue);
	}
}

用信号量解决生产者-消费者问题

在这里插入图片描述
empty 表示空闲缓冲区,当缓冲区空时,生产者等待。full 表示缓冲区使用的数量,与empty相反。
Producer()中,作为生产者,P(empty)V(full),test 有没有空闲缓冲区。
Consumer()中,作为消费者,P(full),V(empty),test 缓冲区是否为空
生产者什么时候会停?
当缓冲区为满时,空闲缓冲区为空时。
消费者什么时候会停?
当缓冲区为空时,缓冲区全部空闲时。

mutex 互斥信号量,初值为1

....
P(mutex) //申请锁 mutex --
{
	......
}
V(mutex)//释放锁 mutex ++;
....

由于mutex初值为1,当进程A申请锁时(P(mutex)),mutex --,此时为0
若此时进程B也申请锁,由于此时进程A已上锁,P(mutex)将会使mutex0改为 -1,此时进程将被sleep()
进程A执行完毕,释放锁(V(mutex)),会使mutex-1改为0,将唤醒进程B,进程B取得锁。
进程B执行完毕,释放锁(V(mutex)),将会使mutex恢复至1.

信号量临界区保护

**什么是信号量?**通过对这个量的访问和修改,让大家有序推进。
为什么要保护信号量?
既然要对这个量访问和修改,那么一定会出现 竞争条件
在这里插入图片描述
竞争条件:和调度有关的共享数据语义错误。
在这里插入图片描述
在这里插入图片描述
临界区:
在这里插入图片描述
读写信号量的代码一定是临界区,加以保护。

保护原则:
在这里插入图片描述

临界区保护的方法

轮换法:

在这里插入图片描述

标记法:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
非对称标记:
在这里插入图片描述

标记与轮换的综合:Peterson算法

在这里插入图片描述
flag[i] 可以理解为:当前要执行i进程
turn = j 可以理解为: 接下来执行j进程

在这里插入图片描述

多个进程:面包店算法

在这里插入图片描述
在这里插入图片描述

硬件法:关中断

在这里插入图片描述
调度由中断产生,控制中断可以组织调度,cli()关中断,sli()开中断
多CPU(多核)无效的原因cli()sli() 会使当前CPU忽略INTR寄存器上的中断标记,但无法控制其他CPU。

硬件法:原子指令法

在这里插入图片描述

信号量代码实现

在这里插入图片描述
(1)信号量数据结构以及应该在内核态,用户态应定义系统调用:sem_open(),调用sem_open()进入内核态调用sys_sem_open()sys_sem_open()中创建信号量。
(2)此生产者要在文件中写入5个数:写之前判断是否有空闲缓冲区:sem_wait()sys_sem_wait中实现P(empty)的功能:

....
cli();//保护信号量
if(semtable[sd].value -- < 0)
	sleep_on(current);
	(semtable[sd].queue).push(current); //加入队列,具体实现略
	schedule();
sti();
....

Linux 0.11 中:
在这里插入图片描述

  1. 获取空闲缓存
  2. 启动读入(上锁)
    在这里插入图片描述
    sleep_on 的实现:
    在这里插入图片描述
    四:进程运行轨迹的跟踪与统计中提到了sleep_on的实现,这个队列的实现及其巧妙。
    在这里插入图片描述
    在这里插入图片描述
    wake_up会将等待队列全部唤醒,然后根据优先级获取资源。
    再回头看lock_buffer():因为全部唤醒,优先级最高的会上锁,其他的再次睡眠。
    在这里插入图片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章