博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
进程同步
阅读量:4079 次
发布时间:2019-05-25

本文共 2334 字,大约阅读时间需要 7 分钟。

进程同步

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

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

一.间接相互制约

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

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

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

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

访问临界资源的循环进程

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)

哲学家问题

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

转载地址:http://gqsni.baihongyu.com/

你可能感兴趣的文章
剑指offer算法题分析与整理(三)
查看>>
JVM并发机制探讨—内存模型、内存可见性和指令重排序
查看>>
nginx+tomcat+memcached (msm)实现 session同步复制
查看>>
WAV文件解析
查看>>
WPF中PATH使用AI导出SVG的方法
查看>>
QT打开项目提示no valid settings file could be found
查看>>
java LinkedList与ArrayList迭代器遍历和for遍历对比
查看>>
coursesa课程 Python 3 programming 统计文件有多少单词
查看>>
多线程使用随机函数需要注意的一点
查看>>
getpeername,getsockname
查看>>
所谓的进步和提升,就是完成认知升级
查看>>
如何用好碎片化时间,让思维更有效率?
查看>>
No.182 - LeetCode1325 - C指针的魅力
查看>>
Encoding Schemes
查看>>
带WiringPi库的交叉笔译如何处理二之软链接概念
查看>>
Java8 HashMap集合解析
查看>>
自定义 select 下拉框 多选插件
查看>>
Linux常用统计命令之wc
查看>>
fastcgi_param 详解
查看>>
搞定Java面试中的数据结构问题
查看>>