进程同步

xiaoxiao2021-02-28  5

进程同步

进程同步机制的主要任务,对多个相关进程在执行次序上进行协调,使并发执行的各进程之间按照一定的规则(或时序)共享系统资源,并能很好的相互合作,从而使程序的执行具有可再现性

共享资源可能会产生的俩种制约关系:

一.间接相互制约

多个程序并发执行(各进程在相同的时间间隔内(比如时间间隔按照时间片的大小)执行,不是同一时刻执行(同一时刻执行是并行执行,可以在多处理机上运用))

当要访问像打印机,磁带机这样的临界资源,必须要保证多个进程互斥的访问这些临界资源,这样便达到了间接互相制约的效果

临界资源:硬临界资源和软临界资源,必须互斥访问

把进入临界资源的代码称为临界区

访问临界资源的循环进程

while(TRUE){

进入区;//临界区之前的一段用于检出的代码

临界区;//如有进程在访问临界资源,需要将访问标志设置为正在访问

退出区;//将正在访问标志恢复为未被访问标志

剩余区;//除了进入区,临界区,退出区的代码之外的部分

}

二.直接相互制约

如输入进程A和计算进程B,它们之间共享一个缓冲区(引入缓冲区的主要原因:①缓和CPU与I/O设备间速度不匹配的矛盾②减少对CPU的中断频率,放宽对CPU中断响应时间的限制③解决数据粒度(数据单元大小)不匹配问题 ④提高CPU和I/O设备之间的并行性),进程A通过缓冲区向进程B提供数据,进程B从缓冲区提取数据,并对数据进行处理,当缓冲区为空时,进程B不能提取数据而堵塞(block),当进程A输入数据到缓冲区后变将进程B唤醒(wakeup),同样,当进程A不能向缓冲区输入数据时(即缓冲区满),进程A堵塞,当进程B向缓冲区提取数据后便将进程A唤醒。这样进程A和进程B便形成了直接相互制约关系

生产者(producer)-消费者(consumer)问题

int in=0,out=0,counter=0;

item buffer[n];//n个缓冲区的缓冲池

void producer(){

while(1){

produce an item in nextp;//每次生产的产品

....

while(counter==n)//判断是不是放满了

;

buffer[in]=nextp;//将产品放入到缓冲池中

in=(in+1)%n;//保证数组下标不越界 in的范围总是在0-n(不含n)中

counter++;

}

};

void consumer(){

while(1){

while(count==0)//判断是不是取完了

;

nextc=buffer[out];//从缓冲池取出产品

out=(out+1)%n;

counter--;

consumer the item in nextc;

.....

}

};

上述程序顺序执行时是正确的 而并发执行就会出现差错 因为他们可以同时共享变量counter

因为加上一把锁 保证互斥共享 如同数据库中的共享锁S(只能读 也称读锁)和排他锁X(可读可写 也称写锁)或Java线程同步机制一样 当线程进入run方法后便为其加上一把锁

等run方法执行完之后再将锁释放掉

因此 为保证正确 需要引入互斥信号量解决进程同步问题

三.经典进程的同步问题

生产者与消费者(用记录型信号量解决)

int  in=0,out=0;

int buffer[n];//n个缓冲区的缓冲池

semaphore mutex=1,empty=n,full=0;//互斥信号量初始值为1 empty 和full为资源信号量

void producer(){

do{

producer an item nextp;

...

wait(empty);//申请空缓冲区

wait(mutex);//利用互斥信号量mutex实现各进程对缓冲池的互斥使用 这里是申请访问 申请成功便获得访问权限 其他进程不能进入该临界区

buffer[in]=nextp;//将产品放入

in=(in+1)%n;

signal(mutex);// 将信号量释放 此时其它进程此时可以进入该临界区进行申请访问

signal(full);//释放资源 空缓冲区现在放了产品进去 即 full+=1

//对于互斥信号量mutex来说 wait和signal(也叫p和v操作,都属于原子操作(要么全部做 要么不做 不可中断)) 它们必要在单个方法中成对出现 

}while(TRUE);

}

void consumer(){

do{

wait(full);//申请有产品的缓冲区

wait(mutex);

nextc=buffer[out];//取出产品

out=(out+1)%n;

signal(mutex);

signal(empty);//释放资源 取走了产品 此时增加空缓冲区 即empty+=1;

consumer the item in nextc;

...

}while(TRUE);

}

void main(){

cobegin

producer();

consumer();

coend

}

生产者与消费者(用AND信号量解决)

只要把wait(empty)和wait(mutex)用Swait(empty,mutex)代替就行 它们是等价的

类似的Ssignal(mutex,full)代替signal(mutex)和signal(full)

哲学家问题

可以规定先让奇数号哲学家先拿他左边的筷子 再去拿右边的筷子 而偶数号哲学家则相反 这样能够避免死锁(产生死锁的四个必要条件:①互斥条件②请求保持条件(不能申请到新的资源又占着原先资源不放)③不可抢占条件④循环等待条件) 又能使哲学家进餐

转载请注明原文地址: https://www.6miu.com/read-1150260.html

最新回复(0)