本文共 1663 字,大约阅读时间需要 5 分钟。
有两个线程:一个生产者线程和一个消费者线程程共享一个初始为空、固定大小为maxbuf的缓存(缓冲区)。生产者的工作是向缓冲区中存数据,只有缓冲区没满时,生产者才能把消息放入到缓冲区,否则必须等待,如此反复; 同时,只有缓冲区不空时,消费者才能从中取出消息,一次消费一个数据(即将其从缓存中移出),否则必须等待。由于缓冲区是临界资源,它只允许一个生产者放入消息,或者一个消费者从中取出消息。
#include#include #include #include #include #include #define maxbuf 5using namespace std;struct Shared //共享的缓冲区{ int buf[maxbuf];};Shared shared;void *produce(void *arg){ //生产者处理函数 for(int x=0;x
我们发现:第3-6行输出是错误的(数据还没产生,就已经被消费。)
我们需要三个信号量:
sem_t *mutex,*empty,*full;
mutex 使得生产者线程和消费者线程可以互斥的执行,因为不能同时生产和消费(类似于互斥锁)。
empty 记录剩余缓冲区的数量(计数信号量)。 full 记录已存放数据的缓存区数量(计数信号量)。#include#include #include #include #include #include #define maxbuf 5using namespace std;struct Shared{ int buf[maxbuf]; sem_t *mutex,*empty,*full; //信号量};Shared shared;void *produce(void *arg){ for(int x=0;x
我们发现:运行结果正常。
#include#include #include #include #include #include #define maxbuf 5using namespace std;struct Shared{ int buf[maxbuf]; sem_t mutex,empty,full;};Shared shared;void *produce(void *arg){ for(int x=0;x
运行结果
相同的结果。
1、有名信号量必须指定一个相关联的文件名称,这个name通常是文件系统中的某个文件;无名信号量不需要指定名称。
2、有名信号量既可用于线程间的同步,又能用于进程间的同步;无名信号量通过shared参数来决定是进程内还是相关进程间共享。
3、有名信号量是随内核持续的,一个进程创建一个信号量,另外的进程可以通过该信号量的外部名(创建信号量使用的文件名)来访问它。进程结束后,信号量还存在,并且信号量的值也不会改动。无名信号量的持续性却是不定的:如果无名信号量是由单个进程内的各个线程共享的,那么该信号量就是随进程持续的,当该进程终止时它也会消失。如果某个无名信号量是在不同进程间同步的,该信号量必须存放在共享内存区中,只要该共享内存区存在,该信号量就存在。