Advertisement
Guest User

Untitled

a guest
Apr 18th, 2015
308
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.05 KB | None | 0 0
  1. #include <stdio.h>      //knihovna pro vstupy a výstupy   
  2. #include <stdlib.h>     //knihovna pro různé funkce
  3. #include <ctype.h>      //knihovna pro testování a mapování znaků
  4. #include <string.h>     //knihovna pro práci se stringy
  5. #include <unistd.h>     //knihovna pro definici různých symbolických konstant a typů a pro různé funkce
  6. #include <signal.h>     //knihovna pro inicializaci signálů
  7. #include <sys/wait.h>   //knihovna deklarace pro čekání
  8. #include <sys/types.h>  //knihovna datových typů 
  9. #include <sys/shm.h>    //knihovna pro sdílenou pamět
  10. #include <sys/ipc.h>    //knihovna pro meziprocesovou komunikaci
  11. #include <sys/stat.h>   //data vrácena ze stat() function
  12. #include <sys/sem.h>    //knivna pro semafory
  13. #include <semaphore.h>  //knihovna pro semafory
  14. #include <fcntl.h>      //knihovna pro kontrolu souborů (nastavení)
  15. #include <sys/mman.h>   //knihovna pro správu paměti
  16. #include <sched.h>      //knihovna plánování
  17. #include <pthread.h>    //knihovna pro vlákna
  18. #include <time.h>       //knihovna pro zjištění času
  19.  
  20. /************************************************* Definice maker *************************************************/
  21. #define CHYBA_PARAM 1
  22. #define CHYBA_POCET 2
  23. #define SYS_ERROR 2
  24. #define CHYBA_ARG1 3
  25. #define CHYBA_ARGS 4
  26. #define CHYBA_FORK 5
  27.  
  28. /************************************************* Deklarace struktury s proměnnými *************************************************/
  29. typedef struct parametry{
  30.     int O;          // O = počet procesů kyslíku
  31.     int H;          //H = vodík,2x počet procesů kyslíku,
  32.     int GH;         //GH = maximální hodnota doby (v milisekundách), po které je generován nový proces pro vodík
  33.     int GO;             //GO = maximální hodnota doby (v milisekundách), po které je generován nový proces pro vodík
  34.     int B;          //B je maximální hodnota doby (v milisekundách) provádění funkce bond
  35.     char *F;        //název výstup. souboru
  36. }Tparam;
  37.  
  38. /*Deklarace globálních proměnných*/
  39. sem_t *s_hydrogen,*s_oxygen,*s_citac_h,*s_citac_o,*s_citac,*s_zap,*s_predbeh,*s_bond;
  40.  
  41. /************************************************** Funkční prototypy **************************************************/
  42. void napoveda();        //nápověda
  43. void oxygen(int i);     //funkce kyslíku
  44. void hydrogen(int i);   //funkce vodíku
  45. void boned();           //funkce na spojení atomů
  46. int nacteni_zdroju(void);   //funkce pro načtení zdrojů
  47. void uklid(void);       //funkce na úklid
  48. int chyba(int cislo);   //funkce pro chyby
  49. int zpracovani_argumentu(int argc,char *argv[],Tparam *x);  //funkce na zpracování argumentů
  50.  
  51. /*************************************************** Funkce pro nápovědu ***************************************************/
  52. void napoveda(){
  53. printf("Autor: Jan Nosál\n"
  54.     "Datum vytvoření: 11.4.2015\n"
  55.     "Název úlohy: Building H20\n"
  56.     "Popis úlohy: Implementujte v jazyce C modifikovaný synchronizační problém Building H20 (můžete se inspirovat knihou The Little Book of Semaphores). Existují dva typy procesů, kyslík a vodík. Aby se mohly spojit do molekuly vody, musí se počkat na příchod příslušných atomů, tj. jeden atom kyslíku a dva atomy vodíku. Poté se spojí do molekuly vody a proces se opakuje.\n");
  57. }
  58.  
  59. /*************************************************** Funkce pro oxygen ***************************************************/
  60. void oxygen(int i){
  61.     printf("O %d Child proces kysliku %d PPID: %d\n",i,getpid(),getppid());
  62.    
  63.  
  64. /*  fprintf"%d: O %d: started",cislo_akce_fce(cislo_akce),i);
  65.     fprintf(zapis,"%d: O %d: ready",cislo_akce_fce(cislo_akce),i);
  66.     fprintf(zapis,"%d: O %d: begin bonding",cislo_akce_fce(cislo_akce),i);
  67.     fprintf(zapis,"%d: O %d: bonded",cislo_akce_fce(cislo_akce),i);
  68.     fprintf(zapis,"%d: O %d: finished",cislo_akce_fce(cislo_akce),i);
  69. */
  70.     exit(0);
  71. }
  72.  
  73. /*************************************************** Funkce pro hydrogen ***************************************************/
  74. void hydrogen(int i){
  75.     printf("H %d Child proces vodiku %d PPID: %d\n",i,getpid(),getppid());
  76.    
  77. /*  fprintf(zapis,"%d: H %d: started",cislo_akce_fce(cislo_akce),i);
  78.     fprintf(zapis,"%d: H %d: waiting",cislo_akce_fce(cislo_akce),i);
  79.     fprintf(zapis,"%d: H %d: begin bonding",cislo_akce_fce(cislo_akce),i);
  80.     fprintf(zapis,"%d: H %d: bonded",cislo_akce_fce(cislo_akce),i);
  81.     fprintf(zapis,"%d: H %d: finished",cislo_akce_fce(cislo_akce),i);
  82. */
  83.     exit(0);
  84. }
  85.  
  86. /*************************************************** Funkce na spojení atomů ****************************************************/
  87. void boned(){
  88.     exit(0);
  89. }
  90.  
  91. /*************************************************** Funkce pro načtení zdrojů ***************************************************/
  92. int init_zdroju(void){
  93.  
  94. /*SEMAFORY*/
  95.     int chyba = 0;
  96.     //s_hydrogen = semafor vodíku
  97.     //s_oxygen = semafor kyslíku
  98.     //s_bond = semafor pro konec spojování
  99.     //s_citac_h = vylucný pristup k citaci vodiku
  100.     //s_citac_o = vylucný pristup k citaci kysliku
  101.     //s_citac = = vylucný pristup k citaci akci
  102.     //s_predbeh = semafor na hlidani, aby se kyslik a vodik nepredbehly
  103.     //s_zap = vylucny pristup k souboru
  104.  
  105.     if((s_hydrogen = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0)) == MAP_FAILED){chyba = 2;}
  106.     if((s_oxygen = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0)) == MAP_FAILED) {chyba = 2;}
  107.     if((s_bond = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0)) == MAP_FAILED) {chyba = 2;}
  108.     if((s_citac_h = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0)) == MAP_FAILED) {chyba = 2;}
  109.     if((s_citac_o = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0)) == MAP_FAILED) {chyba = 2;}
  110.     if((s_citac = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0)) == MAP_FAILED) {chyba = 2;}
  111.     if((s_predbeh = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0)) == MAP_FAILED) {chyba = 2;}
  112.     if((s_zap = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0)) == MAP_FAILED) {chyba = 2;}
  113.  
  114.     if(chyba == 0) {
  115.         if(sem_init(s_hydrogen, 1, 0) == -1) {chyba = 2;}
  116.         if(sem_init(s_oxygen, 1, 0) == -1) {chyba = 2; }
  117.         if(sem_init(s_bond, 1, 0) == -1) {chyba = 2; }
  118.         if(sem_init(s_citac_h, 1, 0) == -1) {chyba = 2;}
  119.         if(sem_init(s_citac_o, 1, 0) == -1) {chyba = 2;}
  120.         if(sem_init(s_citac, 1, 0) == -1) {chyba = 2;}
  121.         if(sem_init(s_predbeh, 1, 0) == -1) {chyba = 2;}
  122.         if(sem_init(s_zap, 1, 0) == -1) {chyba = 2;}
  123.     }
  124. /*KONEC SEMAFORŮ*/
  125.  
  126. /*INICIALIZACE SDÍLENÉ PAMĚTI*/
  127.    
  128. /*KONEC SDÍLENÉ PAMĚTI*/
  129.  
  130. return 0;
  131. }
  132.  
  133. /*************************************************** Funkce na chyby ***************************************************/
  134. int chyba(int cislo){
  135.     switch(cislo){
  136.     case CHYBA_PARAM:
  137.         fprintf(stderr,"Chyba zadani argumentu (argument není číslo nebo je zadán špatný rozsah doby generování atomů)\n");
  138.         break;
  139.     case CHYBA_POCET:
  140.         fprintf(stderr,"Chyba poctu argumentu\n");
  141.         break;
  142.     case CHYBA_ARG1:
  143.         fprintf(stderr,"Počet procesů musí být větší jak nula\n");
  144.         break;
  145.     case CHYBA_ARGS:
  146.         fprintf(stderr,"Maximální hodnota doby generování musí být menší jak 5001\n");
  147.         break;
  148.     case CHYBA_FORK:
  149.         fprintf(stderr,"Fork se nezdařil\n");
  150.         break;
  151.     default: fprintf(stderr,"Doslo k chybe programu\n");
  152.     }
  153. return 0;
  154. }
  155.  
  156. /*************************************************** Funkce na zpracovnání parametrů ***************************************************/
  157. int args(int argc,char *argv[],Tparam *x){
  158.  
  159.     if(argc==5){   
  160.         x->O = atoi(argv[1]);
  161.         x->H = 2*x->O;
  162.         x->GH = atoi(argv[2]);
  163.         x->GO = atoi(argv[3]);
  164.         x->B = atoi(argv[4]);
  165.  
  166.         for(int i = 1;i<5;i++){
  167.             for(int j = 0;argv[i][j] != '\0';j++){
  168.                 if(argv[i][j] > '9' || argv[i][j] < '0'){
  169.                     chyba(CHYBA_PARAM);
  170.                     exit(1);
  171.                 }
  172.             }  
  173.         }
  174.         if(x->O<=0){
  175.             chyba(CHYBA_ARG1);
  176.             exit(1);
  177.         }
  178.         else if(!(x->GH >= 0 && x->GH < 5001) || !(x->GO >= 0 && x->GO < 5001) || !(x->B >= 0 && x->B < 5001)){
  179.             chyba(CHYBA_ARGS); 
  180.             exit(1);
  181.         }
  182.     }
  183.     else if((argc == 2) && (strcmp(argv[1],"--h"))){
  184.         napoveda();
  185.         exit(0);
  186.     }
  187.     else{
  188.         chyba(CHYBA_POCET);
  189.         exit(1);
  190.     }  
  191. return 0;
  192. }
  193.  
  194. /*************************************************** Funkce na úklid ***************************************************/
  195.  
  196. void uklid(void){
  197.     int chyba = 0;
  198.  
  199.         if(chyba == 2){
  200.             if(sem_destroy(s_hydrogen) == -1) { chyba = 2; }
  201.             if(sem_destroy(s_oxygen) == -1) { chyba = 2; }
  202.             if(sem_destroy(s_bond) == -1) { chyba = 2; }
  203.             if(sem_destroy(s_citac_h) == -1) { chyba = 2; }
  204.             if(sem_destroy(s_citac_o) == -1) { chyba = 2; }
  205.             if(sem_destroy(s_citac) == -1) { chyba = 2; }
  206.             if(sem_destroy(s_predbeh) == -1) { chyba = 2; }
  207.             if(sem_destroy(s_zap) == -1) { chyba = 2; }
  208.         }
  209.  
  210.     if(chyba == 2) { fprintf(stderr, "Semafor se nesmazal\n"); }
  211.     //exit(0);
  212. }  
  213.  
  214. /*************************************************** Hlavní funkce ***************************************************/
  215. int main(int argc,char *argv[]){
  216. //  signal(SIGINT,uklid);
  217. //  signal(SIGKILL,uklid);
  218.     Tparam param;
  219.    
  220.     args(argc,argv,&param);                                 //funkce na ověření argumentů
  221.  
  222.     int init = init_zdroju();
  223.         if(init != 0){
  224.             if(init == 2){
  225.                 fprintf(stderr,"Semafor se nevytvořil\n");
  226.                 exit(1);
  227.             }
  228.             uklid();
  229.         }
  230.  
  231.     pid_t pid_hlav,pid_h,pid_o,pid_rod;
  232.     pid_hlav = fork();                                      //vytvoření hlavního procesu
  233.    
  234.     if(pid_hlav == 0){                                      //potomek hlavního procesu
  235.         useconds_t cekani;
  236.  
  237.         for(int i = 1;i<=param.H;i++){                      //generování vodíku
  238.         if(param.GH>0){
  239.             cekani = random()%param.GH*1000;
  240.             usleep(cekani);                                 //čekání na další atom
  241.         }  
  242.         pid_h = fork();                                     //vytvoření procesu pro vodík
  243.             if(pid_h == 0){                                 //potomek procesu vodíku
  244.                 hydrogen(i);                                //funkce pro vodík                
  245.             }
  246.             else if (pid_h > 0){                            //rodič procecu vodíku
  247.                 waitpid(pid_h,NULL,0);
  248.             }
  249.             else if(pid_h < 0){                             //pokud se fork nezdaří
  250.                 chyba(CHYBA_FORK);
  251.                 exit(SYS_ERROR);
  252.             }
  253.         }
  254.     }
  255.     else if(pid_hlav > 0){                                  //rodič hlavního procesu     
  256.        
  257.         pid_rod = fork();
  258.         if(pid_rod == 0){
  259.             useconds_t cekani;
  260.  
  261.             for(int i = 1;i<=param.O;i++){                  //generování kyslíku
  262.             if(param.GO>0){
  263.                 cekani = random()%param.GO*1000;           
  264.                 usleep(cekani);                             //čekání na další atom
  265.             }
  266.             pid_o = fork();                                 //vytvoření procesu pro kyslík                          
  267.                 if(pid_o == 0){                             //potomek procesu pro kyslík
  268.                     oxygen(i);                              //funkce pro kyslík
  269.                 }  
  270.                 else if (pid_o > 0){                        //rodič procesu pro kyslík   
  271.                     waitpid(pid_o,NULL,0);
  272.                 }
  273.                 else if(pid_o < 0){                         //pokud se fork nezdaří
  274.                     chyba(CHYBA_FORK);
  275.                     exit(SYS_ERROR);
  276.                 }
  277.             }
  278.         }
  279.         else if(pid_rod > 0){                               //proces rodiče
  280.             waitpid(pid_rod,NULL,0);       
  281.         }      
  282.         else if(pid_rod < 0){                               //pokud se fork nezdařil
  283.             chyba(CHYBA_FORK);
  284.             exit(SYS_ERROR);
  285.         }
  286.         waitpid(pid_hlav,NULL,0);                  
  287.     }          
  288.  
  289.     else if(pid_hlav < 0){                                  //pokud se fork nezdaříl
  290.         chyba(CHYBA_FORK);
  291.         exit(SYS_ERROR);
  292.     }
  293. return 0;
  294. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement