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.在读者和写者都等待时访问时写者优先.