/* * Przykładowy program dla kursu "POSIX Threads" z wikibooks.pl * * Temat: prywatne dane wątków * * Autor: Wojciech Muła * Ostatnia zmiana: 2010-03-xx */
#include<stdlib.h>#include<stdio.h>#include<pthread.h>#include<errno.h>#include<unistd.h>#include<string.h>#define test_errno(info) do {if (errno) {perror(info); exit(EXIT_FAILURE);}} while(0)pthread_key_tklucz;/* funkcja wypsuje wiersz, poprzedząjąc go prefiksem przypisanym do wątku */voidwyswietl(constchar*napis){char*prefiks=(char*)pthread_getspecific(klucz);if(prefiks==NULL)/* należy zabezpieczyć się przed sytuacją, gdy wywołujący wątek nie przyporządkował nic do klucza */puts(napis);elseprintf("%s: %s\n",prefiks,napis);}//---------------------------------------------------------------------------/* destruktor klucza */voiddestruktor(void*napis){printf("wywołano destruktor, adres pamięci do zwoleniania: %p ('%s')\n",napis,(char*)napis);free(napis);}//---------------------------------------------------------------------------void*watek(void*napis){/* ustawienie prefiksu w lokalnych danych wątku */intstatus=pthread_setspecific(klucz,napis);if(status)fprintf(stderr,"pthread_setspecific: %s\n",strerror(status));elseprintf("adres napisu: %p ('%s')\n",napis,(char*)napis);wyswietl("Witaj w równoległym świecie!");sleep(1);wyswietl("Wątek wykonuje pracę");sleep(1);wyswietl("Wątek zakończony");returnNULL;}//---------------------------------------------------------------------------char*strdup(constchar*);#define N 3intmain(){pthread_tid[N];inti;char*prefiks[3]={"***","!!!","###"};// prefiksy dla komunikatów z wątków/* utworzenie klucza */errno=pthread_key_create(&klucz,destruktor);test_errno("pthread_key_create");/* utworzenie wątków */for(i=0;i<N;i++){errno=pthread_create(&id[i],NULL,watek,(void*)strdup(prefiks[i%3]));test_errno("pthread_create");}/* oczekiwanie na ich zakończenie */for(i=0;i<N;i++)pthread_join(id[i],NULL);/* usunięcie klucza */errno=pthread_key_delete(klucz);test_errno("pthread_key_delete");returnEXIT_SUCCESS;}//---------------------------------------------------------------------------char*strdup(constchar*s){char*d=NULL;if(s){d=(char*)malloc(strlen(s)+1);if(d)strcpy(d,s);}returnd;}//---------------------------------------------------------------------------