Advertisement
Guest User

Untitled

a guest
Dec 22nd, 2014
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.35 KB | None | 0 0
  1. /* Piotr Zieliński, pz347291 zadanie zaliczeniowe 2 */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <sys/types.h>
  6. #include <sys/ipc.h>
  7. #include <sys/msg.h>
  8. #include "dane.h"
  9. #include <signal.h>
  10. #include <fcntl.h>
  11. #include "err.h"
  12. #include <pthread.h>
  13.  
  14. #define MAX_K 100 //maksymalna liczba wątków
  15. int L, K, M, ileWatkow = 0, przetworzone = 0, uprawnionych = 0, wazneGlosy = 0, wszystkieGlosy = 0;
  16. int id_K, id_R, id_A; //id kolejek
  17. int ileRaport = 0, czekaRaport = 0, ileKomis = 0, czekaKomis = 0;
  18. int* czyBylaKomisja;
  19. int *buffer; //pomocnicze do wyniku
  20. int **wyniki;
  21. pierwszyMsg msg;
  22. kolejneMsg msg2;
  23. raportMsg msg3;
  24. kandMsg msg4;
  25. pthread_t thread;
  26. pthread_attr_t attr;
  27. pthread_mutex_t blokujWatki; //gdy za duzo watkow i chcemy część wstrzymać
  28. pthread_mutex_t mutex, mRaport, mKomisja; // mutexy dla "czytelnikow" i "pisarzy"
  29.  
  30. void *komisjaHandler (void *data){
  31.     int i,j, w = 0, En = 0, u, iO ,numerKomisji = *((int *) data);
  32.     int glosyKomis[L+1][K+1];
  33.     for(i=1; i<=L; i++)
  34.         for(j=1; j<=K; j++) glosyKomis[i][j] = 0;
  35.        
  36.     for(;;){
  37.         if (msgrcv(id_K, &msg2, sizeof(kolejneMsg)-sizeof(long), numerKomisji, 0) == -1) syserr("msgrcv");
  38.         if (msg2.l == -1) {
  39.             u = msg2.n;
  40.             iO = msg2.k;
  41.             break;
  42.         }
  43.         else {
  44.             glosyKomis[msg2.l][msg2.k] += msg2.n;
  45.             w++;
  46.         }
  47.     }
  48.     //sumuje  wszystkie wyniki
  49.     for(i=1; i<=L; i++)
  50.         for(j=1; j<=K; j++) En += glosyKomis[i][j];
  51.     msg2.l = En;
  52.     msg2.k = w;
  53.     if (msgsnd(id_K, &msg2, sizeof(kolejneMsg)-sizeof(long), numerKomisji) != 0) syserr("msgsnd");
  54.     //przed sekcją
  55.     pthread_mutex_lock(&mutex);
  56.     if(ileKomis + ileRaport > 0) {
  57.         czekaKomis++;
  58.         pthread_mutex_unlock(&mutex);
  59.         pthread_mutex_lock(&mKomisja);
  60.         czekaKomis--;
  61.     }
  62.     ileKomis++;
  63.     pthread_mutex_unlock(&mutex);
  64.     //sekcja
  65.     for(i=1; i<=L; i++)
  66.         for(j=1; j<=K; j++) wyniki[i][j] += glosyKomis[i][j];
  67.     przetworzone++;
  68.     uprawnionych += u;
  69.     wazneGlosy += iO;
  70.     wszystkieGlosy += En;
  71.     //koniec sekcji
  72.     ileKomis--;
  73.     if(czekaRaport>0) pthread_mutex_unlock(&mRaport);
  74.     else if (czekaKomis>0) pthread_mutex_unlock(&mKomisja);
  75.     else pthread_mutex_unlock(&mutex);
  76.     ileWatkow--;
  77.     return (void*)0;
  78. }
  79.  
  80. void *raportHandler (void *data){
  81.     int i, ii,En = 0, j, l = ((pierwszyMsg *) data)->info;
  82.     pid_t pid = ((pierwszyMsg *) data)->raportPid;
  83.     int glosyRaport[L+1][K+1];
  84.     msg3.mesg_type = pid;
  85.     //przed sekcją
  86.     pthread_mutex_lock(&mutex);
  87.     if (ileKomis + czekaKomis > 0){
  88.         czekaRaport++;
  89.         pthread_mutex_unlock(&mutex);
  90.         pthread_mutex_lock(&mRaport);
  91.         czekaRaport--;
  92.     }
  93.     ileRaport ++;
  94.     if (czekaRaport > 0) pthread_mutex_unlock(&mRaport);
  95.     else pthread_mutex_unlock(&mutex);
  96.     //sekcja
  97.     msg3.M = M;
  98.     msg3.x = przetworzone;
  99.     msg3.z = wazneGlosy;
  100.     msg3.v = wszystkieGlosy - wazneGlosy;
  101.     msg3.y = uprawnionych;
  102.     msg3.liczbaList = L;
  103.     msg3.liczbaKandydatow = K;
  104.     for(i=1; i<=L; i++)
  105.         for(j=1; j<=K; j++) glosyRaport[i][j] = wyniki[i][j];
  106.     //po sekcji
  107.     pthread_mutex_lock(&mutex);
  108.     ileRaport --;
  109.     if ((ileRaport == 0)  && (czekaKomis >0)) pthread_mutex_unlock(&mKomisja);
  110.     else pthread_mutex_unlock(&mutex);
  111.    
  112.     if (msgsnd(id_R, &msg3, sizeof(raportMsg)-sizeof(long), 0) != 0) syserr("msgsnd");
  113.     msg4.mesg_type = pid;
  114.     if (l != 0){
  115.         for (i = 1; i<=K; i++) En += glosyRaport[l][i];
  116.         msg4.En = En;
  117.         for (i = 1; i<=K; i++){
  118.             msg4.kandydat = glosyRaport[l][i];
  119.             if (msgsnd(id_R, &msg4, sizeof(kandMsg)-sizeof(long), 0) != 0) syserr("msgsnd");
  120.         }
  121.     }
  122.     else {
  123.         for (i = 1; i<=L; i++){
  124.             En = 0;
  125.             for (ii = 1; ii<=K; ii++) En += glosyRaport[i][ii];
  126.             for (j = 1; j<=K; j++){
  127.                 msg4.kandydat = glosyRaport[i][j];
  128.                 msg4.En = En;
  129.                 if (msgsnd(id_R, &msg4, sizeof(kandMsg)-sizeof(long), 0) != 0) syserr("msgsnd");
  130.             }
  131.         }
  132.     }
  133.     ileWatkow --;
  134.     return (void*)0;
  135. }
  136.  
  137. void exit_server(int sig){
  138.     //zabicie procesów
  139.     char* zabijKomisja = "killall -9 komisja";
  140.     char* zabijRaport = "killall -9 raport";
  141.     system(zabijKomisja);
  142.     system(zabijRaport);
  143.     if (msgctl(id_K, IPC_RMID, 0) == -1) syserr("msgctl");
  144.     if (msgctl(id_R, IPC_RMID, 0) == -1) syserr("msgctl1");
  145.     if (msgctl(id_A, IPC_RMID, 0) == -1) syserr("msgctl2");
  146.     free(buffer);
  147.     free(wyniki);
  148.     free(czyBylaKomisja);
  149.     exit(0);
  150. }
  151.  
  152. void inicjalizuj(int M, int L, int K){
  153.     int i;
  154.     //kolejki
  155.     if ((id_K = msgget(KKEY, 0666 | IPC_CREAT | IPC_EXCL)) == -1) syserr("msgget");
  156.     if ((id_R = msgget(RKEY, 0666 | IPC_CREAT | IPC_EXCL)) == -1) syserr("msgget1");
  157.     if ((id_A = msgget(AKEY, 0666 | IPC_CREAT | IPC_EXCL)) == -1) syserr("msgget2");
  158.     //tablice alokacja i init
  159.     buffer = malloc(sizeof(int) * (L+1) * (K+1));
  160.     wyniki = malloc(sizeof(int*) * (K+1));
  161.     czyBylaKomisja = malloc (sizeof (int) * M+1);
  162.     for(i = 0; i<=K; i++)
  163.         wyniki[i]=&buffer[i*(L+1)];
  164.     for (i = 1; i <= M; i++) czyBylaKomisja[i] = 0;
  165.     //init mutexy i ustawiamy na 0
  166.     if(pthread_mutex_init(&mutex, 0) != 0 ) syserr("pthread_mutex_init");
  167.     if(pthread_mutex_init(&mKomisja, 0) != 0 ) syserr("pthread_mutex_init");
  168.     if(pthread_mutex_init(&mRaport, 0) != 0 ) syserr("pthread_mutex_init");
  169.     if(pthread_mutex_lock(&mKomisja) != 0) syserr("lock mutex");
  170.     if(pthread_mutex_lock(&mRaport) != 0) syserr("lock mutex");
  171. }
  172.  
  173. int main (int argc, char* argv[]){
  174.     int numerKomisji, l;
  175.     pid_t pid;
  176.     if (signal(SIGINT,  exit_server) == SIG_ERR) syserr("signal");
  177.     L = atoi(argv[1]);  K = atoi(argv[2]); M = atoi(argv[3]);
  178.    
  179.     inicjalizuj(M, L, K);
  180.     for(;;){
  181.         if (msgrcv(id_A, &msg, sizeof(pierwszyMsg)-sizeof(long), 0, 0) == -1) syserr("msgrcv");
  182.         if (msg.mesg_type == 1){
  183.             numerKomisji = msg.info;
  184.             //czy mamy już obsługiwaną taką komisję
  185.             if(czyBylaKomisja[msg.info] == 1){
  186.                 printf("Komisja  już obsłużona / obsługiwana");
  187.                 msg.mesg_type = msg.info;
  188.                 msg.info = 1;
  189.                 if (msgsnd(id_A, &msg, sizeof(pierwszyMsg)-sizeof(long), 0) != 0) syserr("msgsnd");
  190.             }
  191.             else {
  192.                 czyBylaKomisja[msg.info] = 1;
  193.                 msg.mesg_type = msg.info;
  194.                 msg.info = 0;
  195.                 if (msgsnd(id_A, &msg, sizeof(pierwszyMsg)-sizeof(long), 0) != 0) syserr("msgsnd");
  196.                 if (MAX_K <=ileWatkow){
  197.                     //zawieszamy zeby nie bylo za duzo watkow
  198.                     if (pthread_mutex_init(&blokujWatki, 0) != 0) printf("pthread_mutex_init");
  199.                     if (pthread_mutex_lock(&blokujWatki) != 0) syserr("pthread_mutex_lock");
  200.                     if (pthread_mutex_lock(&blokujWatki) != 0) syserr("pthread_mutex_lock2");
  201.                 }
  202.                 //atrybuty wątku
  203.                 if (pthread_attr_init(&attr) != 0 ) syserr("attrinit");
  204.                 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) != 0) syserr("setdetach");
  205.                 ileWatkow++;
  206.                 if (pthread_create(&thread, &attr, &komisjaHandler, &numerKomisji) != 0) syserr("create");
  207.             }
  208.         }
  209.         else{
  210.             l = msg.info;
  211.             pid = msg.raportPid;
  212.             if (MAX_K <=ileWatkow){
  213.                 //zawieszamy zeby nie bylo za duzo watkow
  214.                 if (pthread_mutex_init(&blokujWatki, 0) != 0) printf("pthread_mutex_init");
  215.                 if (pthread_mutex_lock(&blokujWatki) != 0) syserr("pthread_mutex_lock");
  216.                 if (pthread_mutex_lock(&blokujWatki) != 0) syserr("pthread_mutex_lock2");
  217.             }
  218.             //atrybuty wątku
  219.             if (pthread_attr_init(&attr) != 0 ) syserr("attrinit");
  220.             if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) != 0) syserr("setdetach");
  221.             ileWatkow++;
  222.             pierwszyMsg * pomocniczy = (pierwszyMsg *) malloc (sizeof(pierwszyMsg));
  223.             pomocniczy->info = l;
  224.             pomocniczy->raportPid = pid;
  225.             if (pthread_create(&thread, &attr, &raportHandler, pomocniczy) != 0) syserr("create");
  226.         }
  227.     }
  228.     return 0;
  229. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement