读书笔记:第10章 Posix信号量 (3)

《UNIX网络编程:卷2》P192:图10-20 使用基于内存信号量的生产者-消费者程序

------------------------------------------------------------------

/*
 * prodcons2.c
 * P192 图10-20 使用基于内存信号量的生产者-消费者程序
 */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <semaphore.h>
#include <pthread.h>

#define NBUFF		10

void *produce(void *arg);
void *consume(void *arg);

int		nitems;
struct {
	int		buff[NBUFF];		// 可以存放NBUFF个条目的缓冲区
	sem_t	mutex;				// 二值信号量保护生产者和消费者的临界区
	sem_t	nempty;			// 统计共享缓冲区中的空槽位数	
	sem_t	nstored;			// 统计共享缓冲区中已填写的槽位数
} shared;

int main(int argc, char *argv[])
{
	pthread_t	tid_produce;
	pthread_t	tid_consume;

	if (argc != 2) {
		fprintf(stderr, "usage: prodcons1 <#items>\n");
		exit(1);
	}

	nitems = atoi(argv[1]);

	/*
	 * 初始化三个信号量
	 */
	if (sem_init(&shared.mutex, 0, 1) == -1) {
		fprintf(stderr, "sem_init error: %s\n", strerror(errno));
		exit(1);
	}
	if (sem_init(&shared.nempty, 0, NBUFF) == -1) {
		fprintf(stderr, "sem_init error: %s\n", strerror(errno));
		exit(1);
	}
	if (sem_init(&shared.nstored, 0, 0) == -1) {
		fprintf(stderr, "sem_init error: %s\n", strerror(errno));
		exit(1);
	}

	// set_concurrency(2);	// 该函数在Linux上无效

	/*
	 * 创建两个线程,一个作为生产者,一个作为消费者。
	 */
	if (pthread_create(&tid_produce, NULL, produce, NULL) != 0) {
		fprintf(stderr, "pthread_create error: %s\n", strerror(errno));
		exit(1);
	}
	if (pthread_create(&tid_consume, NULL, consume, NULL) != 0) {
		fprintf(stderr, "pthread_create error: %s\n", strerror(errno));
		exit(1);
	}

	/*
	 * 主线程等待这两个线程终止
	 */
	pthread_join(tid_produce, NULL);
	pthread_join(tid_consume, NULL);

	/*
	 * 删除三个信号量
	 */
	sem_destroy(&shared.mutex);
	sem_destroy(&shared.nempty);
	sem_destroy(&shared.nstored);

	exit(0);
}

void *produce(void *arg)
{
	int		i;

	for (i = 0; i < nitems; i++) {
		sem_wait(&shared.nempty);			// 生产者等待到缓冲区中有一个条目的空间
		sem_wait(&shared.mutex);				// 二值信号量保护临界区
		shared.buff[i%NBUFF] = i;			// 生产者在缓冲区中存放条目
		sem_post(&shared.mutex);	
		sem_post(&shared.nstored);			// 增加一个已填写槽位
	}
	return(NULL);
}

void *consume(void *arg)
{
	int		i;

	for (i = 0; i < nitems; i++) {
		sem_wait(&shared.nstored);			// 消费者等待nstroed信号量
		sem_wait(&shared.mutex);				// 二值信号量保护临界区
		if (shared.buff[i % NBUFF] != i)
			printf("buff[%d] = %d\n", i, shared.buff[i % NBUFF]);
		sem_post(&shared.mutex);
		sem_post(&shared.nempty);			// 增加一个空槽位
	}
	return(NULL);
}

你可能感兴趣的:(读书笔记,《UNIX网络编程》)