[Unix系统编程]用信号量实现哲学家就餐问题

概述:不知道是信号量简单,还是信号量太简单,《Advanced Programming in the UNIX Environment》居然不讲。有几个与信号量相关的系统调用,sem_init, sem_wait, sem_trywait, sem_post, sem_getvalue, sem_destory可以通过man sem_init的方式查看帮助文档,确实比较简单,就不再赘述。

下面的例子也很简单,一看就懂,只为练习信号量的使用。

#include <semaphore.h>
#include <pthread.h>
#include "apue.h"
#include "my_err.h" 

#define N 5 // No. of philosopher
#define M 5 // times of eating
sem_t forks[N];

void * thr_philosopher( void *arg);
int main(int argc, char* argv[])
{
	int i = 0; 
	int err;
	pthread_t tid[N];
	void *tret;
	//initilize semaphore
	for (i = 0; i < N; i++)
	{
		if(sem_init(&forks[i], 0, 1) != 0)
		{
			err_quit("init forks error");
		}
	}
	//create thread
	for (i = 0; i < N; i++)
	{
		err = pthread_create(&tid[i], NULL, thr_philosopher, (void *)i);
		if (err != 0)
		{
			err_quit("can't create thread %d: %s\n", i + 1, strerror(err));
		}
	}

	//get the return value
	for (i = 0; i < N; i++)
	{
		err = pthread_join(tid[i], &tret);
		if (err != 0)
		{
			err_quit("can't join with philosopher %d : %s\n", i + 1,
					strerror(err));
		}
		printf("-------------------philosopher %d has done-------------------\n", (int)tret);
	}

	// delete the source of semaphore
	for (i = 0; i < N; i++)
	{
		err = sem_destroy(&forks[i]);
		if (err != 0)
		{
			err_sys("can't destory semaphore");
		}
	}
	exit(0);
}

void * thr_philosopher( void *arg)
{

	/*
	 * here cann't judge arg == NULL
	 * because (void *)0 will lead to arg = NULL
	 */
	int n = M;
	int i = 0;
	i = (int)arg;
	while ( n-- )
	{
		sleep(1);
		if ( i == N - 1)
		{
			sem_wait(&forks[0]);
			sem_wait(&forks[i]);
		}
		else
		{
			sem_wait(&forks[i]);
			sem_wait(&forks[i + 1]);
		}
		printf("philosopher %d is eating\n", i + 1);
		if ( i == N - 1)
		{
			sem_post(&forks[0]);
			sem_post(&forks[i]);
		}
		else
		{
			sem_post(&forks[i]);
			sem_post(&forks[i + 1]);
		}

	}

	return ((void*)i);
}
[Unix系统编程]用信号量实现哲学家就餐问题_第1张图片

你可能感兴趣的:(JOIN,thread,编程,unix,Semaphore,null)