rendered paste body#define _REENTRANT 1#include <signal.h>#include <time.h>#include <stdio.h>#include <stdlib.h>#include <pthread.h> pthread_mutex_t znak_mutex = PTHREAD_MUTEX_INITIALIZER;pthread_mutex_t tablice_mutex = PTHREAD_MUTEX_INITIALIZER;char znak;unsigned int *tablica; // jak 1 to dany watek wypisuje stanchar *tablica_znakow; // znak poszczegolnych watkowpthread_t *tablica_tidow; // tidy poszczegolnych watkowunsigned int ilosc_watkow;unsigned int rozmiar_tablicy;void *worker(void *arg) { int t; unsigned int numer_watku = *(unsigned int *)arg; unsigned int ilosc = 0; char litera; free(arg); t = (((double)rand())/RAND_MAX)*5+1; if (pthread_mutex_lock(&znak_mutex)!=0){ perror("lock in th!"); exit (-1); } litera = znak; if (znak == 'Z') znak = 'A'; else znak++; if (pthread_mutex_unlock(&znak_mutex)!=0){ perror("unlock in th!"); exit (-1); } sleep(t); while (1) { pthread_testcancel(); putchar(litera); ilosc ++; fflush(stdout); if (pthread_mutex_lock(&tablice_mutex)!=0) { perror("lock in loop in th!"); exit (-1); } tablica_znakow[numer_watku] = litera; if (tablica[numer_watku]) { fprintf(stderr,"Watek %d znakow %d\n",numer_watku,ilosc); tablica[numer_watku]=0; } if (pthread_mutex_unlock(&tablice_mutex)!=0){ perror("unlock in loop in th!"); exit (-1); } sleep(1); }; };void sigusr1_handler (int sig) { sigset_t sigset,sigoldset; signal(SIGUSR1,sigusr1_handler); sigfillset(&sigset); if (pthread_sigmask(SIG_SETMASK,&sigset,&sigoldset)!=0) { perror("sigint::sigmask"); return; } if (pthread_mutex_lock(&tablice_mutex)!=0) { perror("mutex lock"); exit (-1); } unsigned int * numer_watku = (unsigned int*)malloc(sizeof (unsigned int)); *numer_watku = rozmiar_tablicy; tablica = realloc(tablica,sizeof(int)*(rozmiar_tablicy+1)); tablica_tidow = realloc(tablica_tidow,sizeof(pthread_t)*(rozmiar_tablicy+1)); tablica_znakow = realloc(tablica_znakow,sizeof(char)*(rozmiar_tablicy+1)); tablica[rozmiar_tablicy]=0; pthread_t *nowy_tid=&tablica_tidow[rozmiar_tablicy]; if (pthread_create(nowy_tid,0,worker,numer_watku)==0){ rozmiar_tablicy++; ilosc_watkow++; } else { perror("pthread_create"); free(numer_watku); } if (pthread_mutex_unlock(&tablice_mutex)!=0) { perror("mutex unlock"); exit (-1); } if (pthread_sigmask(SIG_SETMASK,&sigoldset,0)!=0){ perror("sigint::sigmask"); exit(-1); } };void sigusr2_handler (int sig) { sigset_t sigset,sigoldset; unsigned int n; signal(SIGUSR2,sigusr2_handler); sigfillset(&sigset); if (pthread_sigmask(SIG_SETMASK,&sigset,&sigoldset)!=0) { perror("sigint::sigmask"); return; } fprintf(stderr,"Ilosc watkow: %d\n",ilosc_watkow); if (pthread_mutex_lock(&tablice_mutex)!=0) { perror("mutex lock"); exit (-1); } for (n=0;n<rozmiar_tablicy;n++) tablica[n] =1; if (pthread_mutex_unlock(&tablice_mutex)!=0){ perror("mutex unlock"); exit (-1); } if (pthread_sigmask(SIG_SETMASK,&sigoldset,0)!=0){ perror("sigint::sigmask"); exit(-1); } };void sigint_handler (int sig) { sigset_t sigset,sigoldset; unsigned int n,min; signal(SIGINT,sigint_handler); sigfillset(&sigset); if (pthread_sigmask(SIG_SETMASK,&sigset,&sigoldset)!=0) { perror("sigint::sigmask"); return; } if (pthread_mutex_lock(&tablice_mutex)!=0){ perror("mutex lock"); exit (-1); } if (ilosc_watkow) { for (n=0;n<rozmiar_tablicy;n++) if (tablica_tidow[n]!=0) { min = n; break; } for (n=0;n<rozmiar_tablicy;n++) if ((tablica_znakow[n]<tablica_znakow[min])&&(tablica_tidow[n]!=0)) min = n; if (pthread_cancel(tablica_tidow[min])!=0) perror("pthread_cancel"); tablica_tidow[min] = 0; if (--ilosc_watkow == 0) exit(0); } else exit(0); if (pthread_mutex_unlock(&tablice_mutex)!=0){ perror("mutex unlock"); exit (-1); } if (pthread_sigmask(SIG_SETMASK,&sigoldset,0)!=0){ perror("sigint::sigmask"); exit(-1); }};int main (void){ sigset_t sigset; printf("PID = %d\n",getpid()); sigfillset(&sigset); sigdelset(&sigset, SIGUSR1); sigdelset(&sigset, SIGUSR2); sigdelset(&sigset, SIGINT); if (pthread_sigmask(SIG_SETMASK,&sigset,0)!=0) { perror("main::sigmask"); return -1; } znak = 'A'; tablica = 0; ilosc_watkow = 0; rozmiar_tablicy = 0; srand(time(0)); do { if (signal(SIGUSR1,sigusr1_handler)==SIG_ERR) break; if (signal(SIGUSR2,sigusr2_handler) == SIG_ERR) break; if (signal(SIGINT,sigint_handler) == SIG_ERR) break; while (1) pause(); } while (0); perror("signal"); return -1;}