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;
}

 

运行结果:

wKioL1eM8kPAr5zWAACRy7kec7E057.png

 

 

 

多生产者——多消费者

如果将main函数中的内容稍作修改,变成1个生产者和2个消费者

wKiom1eM8tiQnVGEAAEWMArVCP0492.png

 

    可以看出,这两个生产者 是起冲突的。 而消费者最终读到的,是两个生产者中,后写入的那个生产者写入的内容。

    因此,我们应该做一些限制,使得同一时刻只有一个生产者能够进入临界区,访问临界资源,具体的做法是,加一把“锁”    

    同样的,对于生产者,也应该加一把“锁”,以保证同一时刻只能有一个生产者进行生产(也就是保证生产过程是原子的)

 

    加了锁以后,运行结果如下,果然是正确的

 

完整的代码如下

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