1、生产者——消费者模型
用到的函数:
sem_init() 初始化
sem_destroy() 销毁
sem_wait() 申请、消费资源(申请不到的时候挂起)
sem_post() 生产资源
单生产者——单消费者:
/*************************************************************************
> File Name: my_senc.c
> Author: HonestFox
> Mail: zhweizhi@foxmail.com
> Created Time: Mon 18 Jul 2016 09:04:20 PM CST
************************************************************************/
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
sem_t space_nums;
sem_t data_nums;
#define _SIZE 5
int buf[_SIZE];
void *consumer(void *arg)
{
int index = 0;
while(1)
{
sleep(1);
sem_wait(&data_nums);
int data = buf[index];
printf("consumer done... data is : %d index is : %d\n", data, index);
sem_post(&space_nums);
index++;
index %= _SIZE;
}
}
void *productor(void *arg)
{
int index = 0;
while(1)
{
sem_wait(&space_nums);
buf[index] = rand() % 1234;
printf("productor done ... data is : %d index is : %d\n", buf[index], index);
sem_post(&data_nums);
++index;
index %= _SIZE;
}
}
int main()
{
sem_init(&space_nums, 0, _SIZE);
sem_init(&data_nums, 0, 0);
pthread_t id1, id2;
pthread_create(&id1, NULL, &consumer, NULL);
pthread_create(&id2, NULL, &productor, NULL);
pthread_join(id1, NULL);
pthread_join(id2, NULL);
sem_destroy(&space_nums);
sem_destroy(&data_nums);
return 0;
}
运行结果:
多生产者——多消费者
如果将main函数中的内容稍作修改,变成1个生产者和2个消费者
可以看出,这两个生产者 是起冲突的。 而消费者最终读到的,是两个生产者中,后写入的那个生产者写入的内容。
因此,我们应该做一些限制,使得同一时刻只有一个生产者能够进入临界区,访问临界资源,具体的做法是,加一把“锁”
同样的,对于生产者,也应该加一把“锁”,以保证同一时刻只能有一个生产者进行生产(也就是保证生产过程是原子的)
加了锁以后,运行结果如下,果然是正确的
完整的代码如下
/*************************************************************************
> File Name: my_senc.c
> Author: HonestFox
> Mail: zhweizhi@foxmail.com
> Created Time: Mon 18 Jul 2016 09:04:20 PM CST
************************************************************************/
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
sem_t space_nums;
sem_t data_nums;
pthread_mutex_t consuming = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t producting= PTHREAD_MUTEX_INITIALIZER;
#define _SIZE 6
int buf[_SIZE];
void *consumer(void *arg)
{
int index = 0;
while(1)
{
sleep(1);
sem_wait(&data_nums);
pthread_mutex_lock(&consuming);
int data = buf[index];
printf("NO.%ud consumer done... data is : %d, index = %d\n", pthread_self(), data, index);
sem_post(&space_nums);
index++;
index %= _SIZE;
pthread_mutex_unlock(&consuming);
}
printf("\n");
}
void *productor(void *arg)
{
int index = 0;
while(1)
{
pthread_mutex_lock(&producting);
sem_wait(&space_nums);
buf[index] = rand() % 1234;
printf(" ^ No.%ud productor done ... data is : %d, index = %d\n", pthread_self(), buf[index], index);
sem_post(&data_nums);
++index;
index %= _SIZE;
pthread_mutex_unlock(&producting);
}
}
int main()
{
sem_init(&space_nums, 0, _SIZE);
sem_init(&data_nums, 0, 0);
pthread_mutex_init(&consuming, NULL);
pthread_mutex_init(&producting, NULL);
// 4 consumer, 2 productor
pthread_t p_id1, p_id2, p_id3, p_id4;
pthread_t c_id1, c_id2;
pthread_create(&p_id1, NULL, &consumer, NULL);
// pthread_create(&p_id2, NULL, &consumer, NULL);
// pthread_create(&p_id3, NULL, &consumer, NULL);
// pthread_create(&p_id4, NULL, &consumer, NULL);
pthread_create(&c_id1, NULL, &productor, NULL);
pthread_create(&c_id2, NULL, &productor, NULL);
//
pthread_join(p_id1, NULL);
// pthread_join(p_id2, NULL);
// pthread_join(p_id3, NULL);
// pthread_join(p_id4, NULL);
pthread_join(c_id1, NULL);
// pthread_join(c_id2, NULL);
sem_destroy(&space_nums);
sem_destroy(&data_nums);
return 0;
}
2、读者——写者模型
(以下内容转载自 http://www.cnblogs.com/pangxiaodong/archive/2011/08/12/2136314.html)
细分起来有三种情况,读者优先(默认情况),弱写者优先(实际上,可理解为读者与写者公平),强写者优先。详细情况可见参考中的文中。现在我对这个问题还不是很熟悉,这里主要给出读者优先的实现。
读者优先的要求如下:可以有多个读者同时工作,不能既有读者和写者通过工作,不能有多个写者同时工作。
可以看出,只要当前有一个以上的读者在工作,那么后面再来的读者与写者,写者肯定被挂起,但是读者却可以工作,所以是读者优先。
semaphore read_mutex = 1;
int read_count = 0;
semaphore write_mutex = 1;
void reader() {
while(true) {
P(read_mutex);
if(0 == read_count) { // 只有当前没有读者在工作时,申请的读者才和申请的写者公平比较
P(write_mutex)
}
read_count++;
V(read_mutex);
//读文件
P(read_mutex);
read_count--;
if(0 == read_count)
V(write_mutex);
V(read_mutex);
}
}
void writer() {
while(true) {
P(write_mutex);
//写文件
V(write_mutex);
}
}
而写者优先要满足如下:
1.要让读者与写者之间、以及写者与写者之问要互斥地访同数据集;
2.在无写进程到来时各读者可同时访问数据集;
3.在读者和写者都等待时访问时写者优先.
转载于:https://blog.51cto.com/zhweizhi/1827573