POSIX Threads/Przykładowe programy/Program 8

/*
 *	Przykładowy program dla kursu "POSIX Threads" z wikibooks.pl
 *
 *	Temat:	różne zachowanie mutexów w pthreads przy próbie ponownego
 *		założenia blokady
 *
 *	Autor: Wojciech Muła
 *	Ostatnia zmiana: 2010-03-xx
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#define __USE_UNIX98
#include <pthread.h>

#define test_errno(msg) do{if (errno) {perror(msg); exit(EXIT_FAILURE);}} while(0)

pthread_t id;
pthread_mutex_t mutex;
pthread_mutexattr_t mutexattr;

void* watek(void* _arg) {
	int errno;

	// 1
	puts("przed wykonaniem pthread_mutex_lock (1)");
		errno = pthread_mutex_lock(&mutex);
		test_errno("pthread_mutex_lock (1)");
	puts("... wykonano pthread_mutex_lock (1)");

	// 2
	puts("przed wykonaniem pthread_mutex_lock (2)");
		errno = pthread_mutex_lock(&mutex);
		test_errno("pthread_mutex_lock (2)");
	puts("... wykonano pthread_mutex_lock (2)");

	// 3
	puts("przed wykonaniem pthread_mutex_unlock (2)");
		errno = pthread_mutex_unlock(&mutex);
		test_errno("pthread_mutex_unlock (2)");
	puts("... wykonano pthread_mutex_unlock (2)");

	// 4
	puts("przed wykonaniem pthread_mutex_unlock (1)");
		errno = pthread_mutex_unlock(&mutex);
		test_errno("pthread_mutex_unlock (1)");
	puts("... wykonano pthread_mutex_unlock (1)");

	return NULL;
}
//------------------------------------------------------------------------

int main(int argc, char* argv[]) {
	int errno;

	pthread_mutexattr_init(&mutexattr);

	if (argc > 1) {
		switch (atoi(argv[1])) {
			case 1:
				puts("mutex typu PTHREAD_MUTEX_ERRORCHECK");
				pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_ERRORCHECK);
				break;
			case 2:
				puts("mutex typu PTHREAD_MUTEX_RECURSIVE");
				pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
				break;
			default:
				puts("mutex typu PTHREAD_MUTEX_NORMAL");
				pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_NORMAL);
				break;
		}
	}
	else {
		puts("użycie: program [0|1|2]");
		return EXIT_FAILURE;
	}

	/* inicjalizacja mutexu */
	errno = pthread_mutex_init(&mutex, &mutexattr);
	test_errno("pthread_mutex_init");

	/* utworzenie wątku */
	errno = pthread_create(&id, NULL, watek, NULL);
	test_errno("pthread_create");

	/* oczekiwanie na jego zakończenie */
	pthread_join(id, NULL);
	test_errno("pthread_join");

	puts("program zakończony");
	return EXIT_SUCCESS;
}
//------------------------------------------------------------------------