SHARE
TWEET

Untitled

a guest Dec 8th, 2019 71 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stddef.h>
  2. #include <stdlib.h>
  3. #include <stdarg.h>
  4. #include <stdio.h>
  5. #include <unistd.h>
  6. #include <string.h>
  7. #include <time.h>
  8. #include <pthread.h>
  9. #include <errno.h>
  10. #include <signal.h>
  11.  
  12. #define MAXLINE 4096
  13. #define ELAPSED(start,end) ((end).tv_sec-(start).tv_sec)+(((end).tv_nsec - (start).tv_nsec) * 1.0e-9)
  14. #define ERR(source) (perror(source),\
  15.                      fprintf(stderr,"%s:%d\n",__FILE__,__LINE__),\
  16.                      exit(EXIT_FAILURE))
  17.  
  18. typedef unsigned int UINT;
  19. typedef struct timespec timespec_t;
  20. typedef struct argsDivision {
  21.     pthread_t tid;
  22.     UINT seed;
  23.     int *pL;
  24.     int *pChecked;
  25.     pthread_mutex_t *pmxL;
  26.     pthread_mutex_t *pmxChecked;
  27. } argsDivision_t;
  28. typedef struct argsSignal {
  29.     pthread_t tid;
  30.     sigset_t* pMask;
  31.     int *pQuitFlag;
  32.     pthread_mutex_t *pmxQuitFlag;
  33. } argsSignal_t;
  34.  
  35.  
  36. void readArguments(int argc, char** argv, int *threadsCount);
  37. void* check_division(void*);
  38. void* sig_handler(void*);
  39. void cancel_threads(argsDivision_t* args, int threadsCount);
  40. void msleep(UINT milisec);
  41.  
  42. int main(int argc, char** argv)
  43. {
  44.     srand(time(NULL));
  45.     int threadsCount;
  46.     int L = 1;
  47.     int checked = 0;
  48.     readArguments(argc, argv, &threadsCount);
  49.  
  50.     sigset_t newMask;
  51.     sigemptyset(&newMask);
  52.     sigaddset(&newMask, SIGINT);
  53.     if(pthread_sigmask(SIG_BLOCK, &newMask, NULL)) ERR("pthread_sigmask");
  54.     int quitFlag = 0;
  55.     pthread_mutex_t mxQuitFlag = PTHREAD_MUTEX_INITIALIZER;
  56.     argsSignal_t args;
  57.     args.pQuitFlag = &quitFlag;
  58.     args.pmxQuitFlag = &mxQuitFlag;
  59.     args.pMask = &newMask;
  60.     if(pthread_create(&args.tid, NULL, sig_handler, &args)) ERR("pthread_create");
  61.  
  62.     pthread_mutex_t mxL = PTHREAD_MUTEX_INITIALIZER;
  63.     pthread_mutex_t mxChecked = PTHREAD_MUTEX_INITIALIZER;
  64.     argsDivision_t *divisions = NULL;
  65.     if((divisions = (argsDivision_t*) malloc(sizeof(argsDivision_t) * threadsCount)) == NULL) ERR("malloc");
  66.     for(int i = 0; i < threadsCount; ++i)
  67.     {
  68.         divisions[i].pL = &L;
  69.         divisions[i].pChecked = &checked;
  70.         divisions[i].pmxL = &mxL;
  71.         divisions[i].pmxChecked = &mxChecked;
  72.         divisions[i].seed = rand();
  73.     }
  74.     for(int i = 0; i < threadsCount; ++i)
  75.         if(pthread_create(&divisions[i].tid, NULL, check_division, &divisions[i])) ERR("pthread_create");
  76.     while(1)
  77.     {
  78.         pthread_mutex_lock(&mxQuitFlag);
  79.         if(quitFlag == 1)
  80.         {
  81.             pthread_mutex_unlock(&mxQuitFlag);
  82.             cancel_threads(divisions, threadsCount);
  83.             break;
  84.         }
  85.         pthread_mutex_unlock(&mxQuitFlag);
  86.         msleep(100);
  87.         while(1)
  88.         {
  89.             pthread_mutex_lock(&mxChecked);
  90.             if(checked == threadsCount)
  91.             {
  92.                 checked = 0;
  93.                 pthread_mutex_unlock(&mxChecked);
  94.                 break;
  95.             }
  96.             pthread_mutex_unlock(&mxChecked);
  97.             //msleep(10);
  98.         }
  99.         pthread_mutex_lock(&mxL);
  100.         L += 1;
  101.         //printf("%d\n", L);
  102.         pthread_mutex_unlock(&mxL);
  103.     }
  104.     for(int i = 0; i < threadsCount; ++i)
  105.         if(pthread_join(divisions[i].tid, NULL)) ERR("pthread_join");
  106.     if(pthread_join(args.tid, NULL)) ERR("pthread_join");
  107.     if(pthread_sigmask(SIG_UNBLOCK, &newMask, NULL)) ERR("pthread_sigmask");
  108.     free(divisions);
  109.     exit(EXIT_SUCCESS);
  110. }
  111.  
  112. void readArguments(int argc, char** argv, int *threadsCount)
  113. {
  114.     *threadsCount = 0;
  115.     if (argc >= 2)
  116.         *threadsCount = atoi(argv[1]);
  117.     if (*threadsCount <= 0) {
  118.         printf("Invalid value for 'threadsCount'\n");
  119.         exit(EXIT_FAILURE);
  120.     }
  121. }
  122.  
  123. void* check_division(void* voidArgs)
  124. {
  125.     pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
  126.     argsDivision_t* args = (argsDivision_t*) voidArgs;
  127.     int M = rand_r(&args->seed) % 99 + 2;
  128.     int odlL = 0;
  129.     //printf("%d\n", M);
  130.     while(1)
  131.     {
  132.         pthread_mutex_lock(args->pmxL);
  133.         if(*args->pL <= odlL)
  134.         {
  135.             pthread_mutex_unlock(args->pmxL);
  136.             //msleep(10);
  137.             continue;
  138.         }
  139.         pthread_mutex_lock(args->pmxChecked);
  140.         (*args->pChecked) += 1;
  141.         pthread_mutex_unlock(args->pmxChecked);
  142.         odlL = *args->pL;
  143.         pthread_mutex_unlock(args->pmxL);
  144.         if(odlL % M == 0)
  145.             printf("%d jest podzielne przez %d\n", odlL, M);
  146.         msleep(100);
  147.     }
  148.     return NULL;
  149. }
  150.  
  151. void* sig_handler(void* voidArgs)
  152. {
  153.     argsSignal_t* args = (argsSignal_t*) voidArgs;
  154.     int signo;
  155.     while(1)
  156.     {
  157.         if(sigwait(args->pMask, &signo)) ERR("sigwait");
  158.         switch(signo)
  159.         {
  160.             case SIGINT:
  161.                 pthread_mutex_lock(args->pmxQuitFlag);
  162.                 *args->pQuitFlag = 1;
  163.                 pthread_mutex_unlock(args->pmxQuitFlag);
  164.                 return NULL;
  165.             default:
  166.                 printf("unexpected signal %d\n", signo);
  167.                 exit(1);
  168.         }
  169.     }
  170.     return NULL;
  171. }
  172.  
  173. void cancel_threads(argsDivision_t* args, int threadsCount)
  174. {
  175.     for(int i = 0; i < threadsCount; ++i)
  176.         pthread_cancel(args[i].tid);
  177. }
  178.  
  179. void msleep(UINT milisec)
  180. {
  181.     time_t sec = (int)(milisec / 1000);
  182.     milisec = milisec - sec*1000;
  183.     timespec_t req = {sec, milisec * 1000000L};
  184.     if(nanosleep(&req, &req)) ERR("nanosleep");
  185. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top