Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Piotr Zieliński, pz347291 zadanie zaliczeniowe 2 */
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/msg.h>
- #include "dane.h"
- #include <signal.h>
- #include <fcntl.h>
- #include "err.h"
- #include <pthread.h>
- #define MAX_K 100 //maksymalna liczba wątków
- int L, K, M, ileWatkow = 0, przetworzone = 0, uprawnionych = 0, wazneGlosy = 0, wszystkieGlosy = 0;
- int id_K, id_R, id_A; //id kolejek
- int ileRaport = 0, czekaRaport = 0, ileKomis = 0, czekaKomis = 0;
- int* czyBylaKomisja;
- int *buffer; //pomocnicze do wyniku
- int **wyniki;
- pierwszyMsg msg;
- kolejneMsg msg2;
- raportMsg msg3;
- kandMsg msg4;
- pthread_t thread;
- pthread_attr_t attr;
- pthread_mutex_t blokujWatki; //gdy za duzo watkow i chcemy część wstrzymać
- pthread_mutex_t mutex, mRaport, mKomisja; // mutexy dla "czytelnikow" i "pisarzy"
- void *komisjaHandler (void *data){
- int i,j, w = 0, En = 0, u, iO ,numerKomisji = *((int *) data);
- int glosyKomis[L+1][K+1];
- for(i=1; i<=L; i++)
- for(j=1; j<=K; j++) glosyKomis[i][j] = 0;
- for(;;){
- if (msgrcv(id_K, &msg2, sizeof(kolejneMsg)-sizeof(long), numerKomisji, 0) == -1) syserr("msgrcv");
- if (msg2.l == -1) {
- u = msg2.n;
- iO = msg2.k;
- break;
- }
- else {
- glosyKomis[msg2.l][msg2.k] += msg2.n;
- w++;
- }
- }
- //sumuje wszystkie wyniki
- for(i=1; i<=L; i++)
- for(j=1; j<=K; j++) En += glosyKomis[i][j];
- msg2.l = En;
- msg2.k = w;
- if (msgsnd(id_K, &msg2, sizeof(kolejneMsg)-sizeof(long), numerKomisji) != 0) syserr("msgsnd");
- //przed sekcją
- pthread_mutex_lock(&mutex);
- if(ileKomis + ileRaport > 0) {
- czekaKomis++;
- pthread_mutex_unlock(&mutex);
- pthread_mutex_lock(&mKomisja);
- czekaKomis--;
- }
- ileKomis++;
- pthread_mutex_unlock(&mutex);
- //sekcja
- for(i=1; i<=L; i++)
- for(j=1; j<=K; j++) wyniki[i][j] += glosyKomis[i][j];
- przetworzone++;
- uprawnionych += u;
- wazneGlosy += iO;
- wszystkieGlosy += En;
- //koniec sekcji
- ileKomis--;
- if(czekaRaport>0) pthread_mutex_unlock(&mRaport);
- else if (czekaKomis>0) pthread_mutex_unlock(&mKomisja);
- else pthread_mutex_unlock(&mutex);
- ileWatkow--;
- return (void*)0;
- }
- void *raportHandler (void *data){
- int i, ii,En = 0, j, l = ((pierwszyMsg *) data)->info;
- pid_t pid = ((pierwszyMsg *) data)->raportPid;
- int glosyRaport[L+1][K+1];
- msg3.mesg_type = pid;
- //przed sekcją
- pthread_mutex_lock(&mutex);
- if (ileKomis + czekaKomis > 0){
- czekaRaport++;
- pthread_mutex_unlock(&mutex);
- pthread_mutex_lock(&mRaport);
- czekaRaport--;
- }
- ileRaport ++;
- if (czekaRaport > 0) pthread_mutex_unlock(&mRaport);
- else pthread_mutex_unlock(&mutex);
- //sekcja
- msg3.M = M;
- msg3.x = przetworzone;
- msg3.z = wazneGlosy;
- msg3.v = wszystkieGlosy - wazneGlosy;
- msg3.y = uprawnionych;
- msg3.liczbaList = L;
- msg3.liczbaKandydatow = K;
- for(i=1; i<=L; i++)
- for(j=1; j<=K; j++) glosyRaport[i][j] = wyniki[i][j];
- //po sekcji
- pthread_mutex_lock(&mutex);
- ileRaport --;
- if ((ileRaport == 0) && (czekaKomis >0)) pthread_mutex_unlock(&mKomisja);
- else pthread_mutex_unlock(&mutex);
- if (msgsnd(id_R, &msg3, sizeof(raportMsg)-sizeof(long), 0) != 0) syserr("msgsnd");
- msg4.mesg_type = pid;
- if (l != 0){
- for (i = 1; i<=K; i++) En += glosyRaport[l][i];
- msg4.En = En;
- for (i = 1; i<=K; i++){
- msg4.kandydat = glosyRaport[l][i];
- if (msgsnd(id_R, &msg4, sizeof(kandMsg)-sizeof(long), 0) != 0) syserr("msgsnd");
- }
- }
- else {
- for (i = 1; i<=L; i++){
- En = 0;
- for (ii = 1; ii<=K; ii++) En += glosyRaport[i][ii];
- for (j = 1; j<=K; j++){
- msg4.kandydat = glosyRaport[i][j];
- msg4.En = En;
- if (msgsnd(id_R, &msg4, sizeof(kandMsg)-sizeof(long), 0) != 0) syserr("msgsnd");
- }
- }
- }
- ileWatkow --;
- return (void*)0;
- }
- void exit_server(int sig){
- //zabicie procesów
- char* zabijKomisja = "killall -9 komisja";
- char* zabijRaport = "killall -9 raport";
- system(zabijKomisja);
- system(zabijRaport);
- if (msgctl(id_K, IPC_RMID, 0) == -1) syserr("msgctl");
- if (msgctl(id_R, IPC_RMID, 0) == -1) syserr("msgctl1");
- if (msgctl(id_A, IPC_RMID, 0) == -1) syserr("msgctl2");
- free(buffer);
- free(wyniki);
- free(czyBylaKomisja);
- exit(0);
- }
- void inicjalizuj(int M, int L, int K){
- int i;
- //kolejki
- if ((id_K = msgget(KKEY, 0666 | IPC_CREAT | IPC_EXCL)) == -1) syserr("msgget");
- if ((id_R = msgget(RKEY, 0666 | IPC_CREAT | IPC_EXCL)) == -1) syserr("msgget1");
- if ((id_A = msgget(AKEY, 0666 | IPC_CREAT | IPC_EXCL)) == -1) syserr("msgget2");
- //tablice alokacja i init
- buffer = malloc(sizeof(int) * (L+1) * (K+1));
- wyniki = malloc(sizeof(int*) * (K+1));
- czyBylaKomisja = malloc (sizeof (int) * M+1);
- for(i = 0; i<=K; i++)
- wyniki[i]=&buffer[i*(L+1)];
- for (i = 1; i <= M; i++) czyBylaKomisja[i] = 0;
- //init mutexy i ustawiamy na 0
- if(pthread_mutex_init(&mutex, 0) != 0 ) syserr("pthread_mutex_init");
- if(pthread_mutex_init(&mKomisja, 0) != 0 ) syserr("pthread_mutex_init");
- if(pthread_mutex_init(&mRaport, 0) != 0 ) syserr("pthread_mutex_init");
- if(pthread_mutex_lock(&mKomisja) != 0) syserr("lock mutex");
- if(pthread_mutex_lock(&mRaport) != 0) syserr("lock mutex");
- }
- int main (int argc, char* argv[]){
- int numerKomisji, l;
- pid_t pid;
- if (signal(SIGINT, exit_server) == SIG_ERR) syserr("signal");
- L = atoi(argv[1]); K = atoi(argv[2]); M = atoi(argv[3]);
- inicjalizuj(M, L, K);
- for(;;){
- if (msgrcv(id_A, &msg, sizeof(pierwszyMsg)-sizeof(long), 0, 0) == -1) syserr("msgrcv");
- if (msg.mesg_type == 1){
- numerKomisji = msg.info;
- //czy mamy już obsługiwaną taką komisję
- if(czyBylaKomisja[msg.info] == 1){
- printf("Komisja już obsłużona / obsługiwana");
- msg.mesg_type = msg.info;
- msg.info = 1;
- if (msgsnd(id_A, &msg, sizeof(pierwszyMsg)-sizeof(long), 0) != 0) syserr("msgsnd");
- }
- else {
- czyBylaKomisja[msg.info] = 1;
- msg.mesg_type = msg.info;
- msg.info = 0;
- if (msgsnd(id_A, &msg, sizeof(pierwszyMsg)-sizeof(long), 0) != 0) syserr("msgsnd");
- if (MAX_K <=ileWatkow){
- //zawieszamy zeby nie bylo za duzo watkow
- if (pthread_mutex_init(&blokujWatki, 0) != 0) printf("pthread_mutex_init");
- if (pthread_mutex_lock(&blokujWatki) != 0) syserr("pthread_mutex_lock");
- if (pthread_mutex_lock(&blokujWatki) != 0) syserr("pthread_mutex_lock2");
- }
- //atrybuty wątku
- if (pthread_attr_init(&attr) != 0 ) syserr("attrinit");
- if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) != 0) syserr("setdetach");
- ileWatkow++;
- if (pthread_create(&thread, &attr, &komisjaHandler, &numerKomisji) != 0) syserr("create");
- }
- }
- else{
- l = msg.info;
- pid = msg.raportPid;
- if (MAX_K <=ileWatkow){
- //zawieszamy zeby nie bylo za duzo watkow
- if (pthread_mutex_init(&blokujWatki, 0) != 0) printf("pthread_mutex_init");
- if (pthread_mutex_lock(&blokujWatki) != 0) syserr("pthread_mutex_lock");
- if (pthread_mutex_lock(&blokujWatki) != 0) syserr("pthread_mutex_lock2");
- }
- //atrybuty wątku
- if (pthread_attr_init(&attr) != 0 ) syserr("attrinit");
- if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) != 0) syserr("setdetach");
- ileWatkow++;
- pierwszyMsg * pomocniczy = (pierwszyMsg *) malloc (sizeof(pierwszyMsg));
- pomocniczy->info = l;
- pomocniczy->raportPid = pid;
- if (pthread_create(&thread, &attr, &raportHandler, pomocniczy) != 0) syserr("create");
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement