一、资源竞争解决技术
上篇介绍互斥锁机制用来解决互斥访问的问题;但线程间仍存在顺序问题,因此我们有了信号量的出现。
P操作:使用这个资源(个数减1)。尝试获取资源;有则用,无则等。
V操作:产生这个资源(个数加1)。释放一个资源;如果有任务则等,无任务则用。
1、公共资源角色
buf[1024]公共资源。
(1)写线程——写资源
可写数据条件:①开始,有空buf; ②读线程,读完了。
p(写资源) //申请资源
V(读资源)//产生资源
(2)读线程——读资源
开始,buf中无数据可读,此时充当写资源。
可读数据条件:写线程结束。
P(读资源)
V(写资源)
2、信号量机制
本质:锁(可顺序操作的一把锁);信号量反映的是资源的个数。
功能:实现了一种可以让线程间有序访问临界资源的方式。
步骤:
(1)信号量的定义
sem_t(信号量类型) sem(信号量变量) //造了一类资源;
(2)信号量的初始化
int sem_init(sem_t *sem , int pshared(使用信号量;0为线程间,非0为进程间) , unsigned int value(资源个数))
无名信号量——线程间通信;有名信号量——进程间通信。
(3)信号量的PV操作
a. int sem_wait(sem_t *sem); //P操作
p操作:使用该资源 资源个数-1
表示使用这个资源,资源个数减1
p操作逻辑
尝试获取资源,
有资源可用,直接使用,资源个数减一
如果没有资源可用,此时等待
b. int sem_post(sem_t *sem); //V操作
v操作:产生该资源 资源个数+1
操作逻辑:
释放一个资源,此时如果有任务,在等待这个资源,这个资源直接给对应的任务;
(4)信号量的销毁
int sem_destroy(sem_t *sem)
二、进程间的通信
1、进程间通信方式
同一主机:
(1)古老的通信方式:管道:①无名管道 ②有名管道;
③信号;
(2)IPC对象通信:System v BSD Suse fedora kernel.org
④消息队列; ⑤共享内存(*)(最高效); ⑥信号量集(信号量);
不同主机:
(3)socket通信:⑦网络通信。
2、无名管道
(1)创建
int pipe(int pipefd[2](管道两端))
两端:pipefd[0] 读端;pipefd[1] 写段。 单向管道
(2)管道的特点
①管道大小65536字节(64k);②管道操作特点:数据读走之后就清空了。
(3)管道读写规则
1)写管道:
①//写端存在,读端也存在
管道若为空,可一直写,直到写满后阻塞。
②//写端存在,读端不存在
写操作会导致管道破裂。(收到信号SIGPIPE,会使程序结束)
2)读管道:
①//写端存在,读端也存在
可读管道,但若管道中无数据,则读操作阻塞。
②//写段不存在,读端存在
可读管道,但若管道中无数据,则读操作不阻塞。
父进程发送字符给子进程,子进程接受并读取