您的位置:首页 > 其它

操作系统基础及多线程/进程同步

2016-04-16 20:14 323 查看


操作系统基础


程序VS进程(Process)VS线程(Thread)

程序是指令的集合,静态文本

进程是程序在一个数据集上运行的过程,进行资源分配和调度的单元

线程是进程中的实体,被系统独立调度和执行的基本单元,可共享资源


进程间通信方法

管道,信号量,消息队列,套接字
管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。

有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。

信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大

套接字( socket ) : 套解口也是一种进程间通信机制,与其他通信机制不同的是。它可用于不同进程间的进程通信,指定端口号即可。


线程同步与互斥概念

线程同步:

使并发执行的各线程之间能够有效的共享资源。
互斥VS同步:

AB竞争资源的相互制约叫做互斥;A做完提供给B,B才能继续做,有先后顺序,叫做同步。互斥是一种特殊的同步。
同步VS异步:

同步必须有先后,异步无所谓先后。
多线程同步互斥的常见方法:

事件event、互斥量,互斥锁mutex、信号量PV。

事件:事件能够通知一个线程的操作已经完成。

互斥量:所有权

信号量:信号量可以计算资源当前剩余量,是一个计数器。


临界资源和临界区

临界资源:一段时间内只允许一个线程访问的资源就称为临界资源或独占资源

临界区:访问临界资源的代码称为临界区


进程间同步问题

参考

#操作系统


多线程同步


生产者消费者


描述

生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例。该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。


解析

需要保证两个方面的同步:

缓冲区操作互斥

生产者和消费者不能同时操作一个缓冲区
剩余容量的的同步

生产者不能在缓冲区满的情况下生产数据,消费者不能在缓冲区为空的情况下消耗数据


伪代码

Semaphore mutex = 1
Semaphore empty_num = size, product_num = 0

producer:
while(1):
P(empty_num)
P(mutex)
produce()
V(mutex)
V(product_num)

customer:
while(1):
P(product_num)
P(mutex)
custome()
V(mutex)
V(empty_num)


读者写着问题

读者—写者问题(Readers-Writers problem)也是一个经典的并发程序设计问题,是经常出现的一种同步问题。计算机系统中的数据(文件、记录)常被多个进程共享,但其中某些进程可能只要求读数据(称为读者Reader);另一些进程则要求修改数据(称为写者Writer)。就共享数据而言,Reader和Writer是两组并发进程共享一组数据区,要求:

(1)允许多个读者同时执行读操作;

(2)不允许读者、写者同时操作;

(3)不允许多个写者同时操作。


读者优先VS写者优先

多个读者可以同时读,在读文件的时候不能写,在写文件的时候不能读。

读者优先

读者可以连续不断来,只要有读者,写者就不能写
写者优先

一旦有写者来,之后的读者必须等待


读者优先

需要如下信号量:

read_count 记录读者个数
writer 记录写者互斥
mutex 保证read_count和writer的修改操作是互斥的

Semaphore read_count = 0
Semaphore mutex = 1, writer = 1

reader:
while(1):
P(mutex)
read_count++
if(read_count == 1)
P(writer)
V(mutex)
read()
P(mutex)
read_count--
if(read_count == 0)
V(writer)
V(mutex)

writer:
while(1):
P(writer)
wirte()
V(wirter)


写者优先

需要增加一个互斥锁,负责当有写者的时候阻塞之后的读者。
Semaphore read_count = 0
Semaphore mutex = 1, writer = 1, queue = 1

reader:
while(1):
P(queue)
P(mutex)
read_count++
if(read_count == 1)
P(writer)
V(mutex)
V(queue)
read()
P(mutex)
read_count--
if(read_count == 0)
V(writer)
V(mutex)

writer:
while(1):
P(queue)
P(writer)
wirte()
V(wirter)
V(queue)


哲学家就餐问题


问题描述

哲学家就餐问题可以这样表述,假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。吃东西的时候,他们就停止思考,思考的时候也停止吃东西。餐桌中间有一大碗意大利面,每两个哲学家之间有一只餐叉。因为用一只餐叉很难吃到意大利面,所以假设哲学家必须用两只餐叉吃东西。他们只能使用自己左右手边的那两只餐叉。哲学家就餐问题有时也用米饭和筷子而不是意大利面和餐叉来描述,因为很明显,吃米饭必须用两根筷子。


解析

对于每一个哲学家,需要拿起左边的筷子,拿起右边的筷子,吃。
Semaphore chopsticks

while(1)
P(chopsticks[i])
P(chopsticks[i+1]%N)
eat()
V(chopsticks[i+1]%N)
V(chopsticks[i])


#操作系统
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: