如图所示,有三个生产者,两个消费者(注意该图所指向仅表示写入数据,并不代表写入同一个空间,读取亦是),设置两个信号量用来控制生产者消费者的运行,首先注意不能先加锁,如果缓冲区满了,此时s1=0,p操作就会阻塞,以至于加锁后无法解锁,所以应该先p操作再加锁,加完锁后就可以开始写入数据,写完后解锁,然后给消费者的信号量+1,这样消费者就可以读取操作了。注意生产者消费者模型并不是生产者将数据生产完后,消费者才能读,是一边生产一边读取。
根据三的图,我们可以用代码来实现该操作
- #include
- #include
- #include
- #include
- #include
- #include
- #define BUFF_SIZE 10
- sem_t product_sem;
- sem_t consume_sem;
- pthread_mutex_t mutex;
- int buff[BUFF_SIZE];
- int in=0;
- int out=0;
-
- void*pro_fun(void*arg)//生产者
- {
- for(int i=0;i<20;i++)
- {
- sem_wait(&product_sem);
- pthread_mutex_lock(&mutex);
- buff[in]=rand()%100;
- printf("生产者在%d处产生数据%d\n",in,buff[in]);
- in=(++in)%10;
- pthread_mutex_unlock(&mutex);
- sem_post(&consume_sem);
- }
- }
- void*con_fun(void*arg)//消费者
- {
- for(int i=0;i<30;i++)
- {
- sem_wait(&consume_sem);
- pthread_mutex_lock(&mutex);
- printf("----------消费者在%d处消费数据%d\n",out,buff[out]);
- out=(++out)%10;
- pthread_mutex_unlock(&mutex);
- sem_post(&product_sem);
- }
- }
- int main()
- {
- sem_init(&product_sem,0,BUFF_SIZE);
- sem_init(&consume_sem,0,0);
- pthread_mutex_init(&mutex,NULL);
- srand((time(NULL)));
- pthread_t pro_id[3];
- for(int i=0;i<3;i++)
- {
- pthread_create(&pro_id[i],NULL,pro_fun,NULL);
- }
- pthread_t con_id[2];
- for(int i=0;i<2;i++)
- {
- pthread_create(&con_id[i],NULL,con_fun,NULL);
- }
- for(int i=0;i<3;i++)
- {
- pthread_join(pro_id[i],NULL);
- }
- for(int i=0;i<2;i++)
- {
- pthread_join(con_id[i],NULL);
- }
- sem_destroy(&product_sem);
- sem_destroy(&consume_sem);
- pthread_mutex_destroy(&mutex);
- exit(0);
-
- }
该方法可以精确记录空闲和数据的个数。
- #include
- #include
- #include
- #include
- #include
- #include
- #define BUFF_SIZE 10
-
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- int buff[BUFF_SIZE];
- int in = 0;
- int out = 0;
-
- void* pro_fun(void* arg) {
- for (int i = 0; i < 20; i++) {
- pthread_mutex_lock(&mutex);
-
- while ((in + 1) % BUFF_SIZE == out) {
- pthread_cond_wait(&cond, &mutex);
- }//如果生产者生产数据值满了,通知消费者
-
- buff[in] = rand() % 100;
- printf("生产者在%d处产生数据%d\n", in, buff[in]);
- in = (in + 1) % BUFF_SIZE;
-
- pthread_cond_signal(&cond);
- pthread_mutex_unlock(&mutex);
- }
- return NULL;
- }
-
- void* con_fun(void* arg) {
- for (int i = 0; i < 30; i++) {
- pthread_mutex_lock(&mutex);
-
- while (in == out) {
- pthread_cond_wait(&cond, &mutex);
- }//如果消费者消费完,通知生产者生产数据
-
- printf("----------消费者在%d处消费数据%d\n", out, buff[out]);
- out = (out + 1) % BUFF_SIZE;
-
- pthread_cond_signal(&cond);
- pthread_mutex_unlock(&mutex);
- }
- return NULL;
- }
-
- int main() {
- pthread_cond_init(&cond, NULL);
- pthread_mutex_init(&mutex, NULL);
- srand(time(NULL));
-
- pthread_t pro_id[3];
- for (int i = 0; i < 3; i++) {
- pthread_create(&pro_id[i], NULL, pro_fun, NULL);
- }
-
- pthread_t con_id[2];
- for (int i = 0; i < 2; i++) {
- pthread_create(&con_id[i], NULL, con_fun, NULL);
- }
-
- for (int i = 0; i < 3; i++) {
- pthread_join(pro_id[i], NULL);
- }
- for (int i = 0; i < 2; i++) {
- pthread_join(con_id[i], NULL);
- }
-
- pthread_cond_destroy(&cond);
- pthread_mutex_destroy(&mutex);
-
- exit(0);
- }

如果对条件变量和信号量不明白的uu可以看一下上几章的内容。后面就要开启网络编程咧。