进程同步和信号量
2016-05-01 22:51
134 查看
进程的同步
进程合作:多进程完成同一个任务
实例1:
司机 售票员
while)true){ while)true){
等待 启动车辆; 关门; 发送信号
正常运行; 售票;
到站停车;发送信号 等待 开门;
} }
两个进程如何实现同步合作? 通过信号
实例2:文档打印
问题:如果进程之间完全不知道对方的存在,会产生怎样的错误?联系实际
实际上的例子:生产者-消费者实例
共享数据
这些都是用户态
生产者进程
while(true){
while(counter == BUFFER_SIZE)
; //阻塞 缓冲区满,生产者停
buffer[in] = item;
in = (in+1)%BUFFER_SIZE;
counter++; //发信号让消费者走
}
消费者进程
while(true){
while(counter == 0)
; //阻塞 缓冲区空,消费者停
item=buffer[out];
out = (out-1)%BUFFER_SIZE;
counter--; //发信号让生产者走
}
等待是进程同步的核心
什么是进程同步?什么地方停,什么地方走?
进程同步 事实上就是让进城走走停停,来保证多进程合作的合理有序
只发信号还不能解决全部问题
1.缓冲区满以后生产者P1生产一个item放入,会sleep
2.有一个生产者P2生产一个item放入,会sleep
3.消费者C执行1次循环,counter == BUFFER_SIZE - 1, 发信号给P1, P1 wake up。
4.消费者C再执行1次循环,counter == BUFFER_SIZE - 2,P2不能被唤醒。
counter无法区分有多少生产者进程,不仅需要唤醒进程(发送信号),还需要一个量用来记录睡眠进程的数量,来决定是否要发信号。
这就引出了信号量。
从信号到信号量
不只是等待信号,发信号? 对应睡眠和唤醒
还能记录一些信息
能记录有2个进程等待就可以了 可以使用优先队列或者是栈来存储
1.缓冲区满,P1执行,P1 sleep,记录下一个进程等待 sem = -1
2.P2执行,P2sleep,记录下两个进程等待 sem = -2
3.C执行1次循环,发现两个进程等待,wakeup一个 wakeup P1 sem=-1
C再执行1次循环,发现一个进程等待,wakeup一个 wakeup P2 sem=0
C再执行1次循环4,发现没有进程等待,sem = 1
P3执行
总结:
什么时候减一?
当有一个进程sleep,信号量-1
什么时候加一?
当发现信号量是负的,信号量+1,并且发信号wakeup; 如果发现信号量是正的,那么不发信号,累加信号量。
问题:一种资源的数量是8,这个资源对应的信号量的当前值是2,说明():
资源的数量是8,说明初始的sem是8,当前的信号量变为2,说明没有进程在等待等待这个资源。
什么是信号量?信号量的定义
信号量:1965年,由荷兰学者Dijkstra提出的一种特殊变量,量用来记录,信号用来sleep和wakeup
struct semaphore
{
int value; //记录资料个数
PCB *queue; //记录等待在该信号量上的进程
}
P(semaphore s); //消费资源
V(semphore s); //产生资源
P(semphore s)
{
s.value--;
if(s.value < 0){
sleep(s.queue);
}
}
问:V(s)的代码?
V(semphore s){
s.value++;
if(s.value <= 0){
wakeup(s.queue);
}
}
Producer(item){
P(empty);
P(mutex);
读入in;将item写入到in的位置上;
V(mutex);
V(full);
}
Constumer() {
P(full);
P(mutex);
读入out;从文件out位置读出到item;打印item;
V(mutex);
V(empty);
}
用信号量解决生产者-消费者问题
int fd = open("buffer.txt");
write(fd, 0, sizeof(int)); //写in
write(fd, 0, sizeof(int)); //写out
semaphore full = 0;
semaphore empty = BUFFER_SIZE;
semaphore mutex = 1;
如何理解用信号量的生产者消费者代码?
full用来判断是否为空,empty用来判断是否为满。通过P和V来睡眠和唤醒进程,并释放信号量。
如何实现互斥访问?
当进入缓冲区时,将mutex的值变为0,用完之后在释放。
进程合作:多进程完成同一个任务
实例1:
司机 售票员
while)true){ while)true){
等待 启动车辆; 关门; 发送信号
正常运行; 售票;
到站停车;发送信号 等待 开门;
} }
两个进程如何实现同步合作? 通过信号
实例2:文档打印
问题:如果进程之间完全不知道对方的存在,会产生怎样的错误?联系实际
实际上的例子:生产者-消费者实例
共享数据
这些都是用户态
生产者进程
while(true){
while(counter == BUFFER_SIZE)
; //阻塞 缓冲区满,生产者停
buffer[in] = item;
in = (in+1)%BUFFER_SIZE;
counter++; //发信号让消费者走
}
消费者进程
while(true){
while(counter == 0)
; //阻塞 缓冲区空,消费者停
item=buffer[out];
out = (out-1)%BUFFER_SIZE;
counter--; //发信号让生产者走
}
等待是进程同步的核心
什么是进程同步?什么地方停,什么地方走?
进程同步 事实上就是让进城走走停停,来保证多进程合作的合理有序
只发信号还不能解决全部问题
1.缓冲区满以后生产者P1生产一个item放入,会sleep
2.有一个生产者P2生产一个item放入,会sleep
3.消费者C执行1次循环,counter == BUFFER_SIZE - 1, 发信号给P1, P1 wake up。
4.消费者C再执行1次循环,counter == BUFFER_SIZE - 2,P2不能被唤醒。
counter无法区分有多少生产者进程,不仅需要唤醒进程(发送信号),还需要一个量用来记录睡眠进程的数量,来决定是否要发信号。
这就引出了信号量。
从信号到信号量
不只是等待信号,发信号? 对应睡眠和唤醒
还能记录一些信息
能记录有2个进程等待就可以了 可以使用优先队列或者是栈来存储
1.缓冲区满,P1执行,P1 sleep,记录下一个进程等待 sem = -1
2.P2执行,P2sleep,记录下两个进程等待 sem = -2
3.C执行1次循环,发现两个进程等待,wakeup一个 wakeup P1 sem=-1
C再执行1次循环,发现一个进程等待,wakeup一个 wakeup P2 sem=0
C再执行1次循环4,发现没有进程等待,sem = 1
P3执行
总结:
什么时候减一?
当有一个进程sleep,信号量-1
什么时候加一?
当发现信号量是负的,信号量+1,并且发信号wakeup; 如果发现信号量是正的,那么不发信号,累加信号量。
问题:一种资源的数量是8,这个资源对应的信号量的当前值是2,说明():
资源的数量是8,说明初始的sem是8,当前的信号量变为2,说明没有进程在等待等待这个资源。
什么是信号量?信号量的定义
信号量:1965年,由荷兰学者Dijkstra提出的一种特殊变量,量用来记录,信号用来sleep和wakeup
struct semaphore
{
int value; //记录资料个数
PCB *queue; //记录等待在该信号量上的进程
}
P(semaphore s); //消费资源
V(semphore s); //产生资源
P(semphore s)
{
s.value--;
if(s.value < 0){
sleep(s.queue);
}
}
问:V(s)的代码?
V(semphore s){
s.value++;
if(s.value <= 0){
wakeup(s.queue);
}
}
Producer(item){
P(empty);
P(mutex);
读入in;将item写入到in的位置上;
V(mutex);
V(full);
}
Constumer() {
P(full);
P(mutex);
读入out;从文件out位置读出到item;打印item;
V(mutex);
V(empty);
}
用信号量解决生产者-消费者问题
int fd = open("buffer.txt");
write(fd, 0, sizeof(int)); //写in
write(fd, 0, sizeof(int)); //写out
semaphore full = 0;
semaphore empty = BUFFER_SIZE;
semaphore mutex = 1;
如何理解用信号量的生产者消费者代码?
full用来判断是否为空,empty用来判断是否为满。通过P和V来睡眠和唤醒进程,并释放信号量。
如何实现互斥访问?
当进入缓冲区时,将mutex的值变为0,用完之后在释放。
相关文章推荐
- CentOS SSH安装与配置
- hdu 3669 Cross the Wall(给你n个矩形,长宽已知,求用不超过k个大矩形包含所有给定矩形,使得大矩形总面积和最小)
- URI、URL和URN的区别
- 进程同步(二)—— 信号量&内存共享
- 用CPPUnit做单元测试
- 数据库中乐观锁与悲观锁的概念
- 专题三 第六题
- hdu1829(A Bug's Life)
- 士兵杀敌(一)
- 20145335郝昊《java程序设计》第9周学习总结
- 20145335郝昊第四次实验报告
- mysql乱码
- 最长公共子序列 nlogn
- Poj 2891 Strange Way to Express Integers【crt】
- leetcode 070 climbing stairs
- Undefined symbols for architecture x86_64错误
- HTML5 摇一摇加强版之一次失败的探索
- bzoj1050:[HAOI2006]旅行comf
- android 动态添加控件控制属性问题
- 深度剖析:如何实现一个 Virtual DOM 算法