Guest User

Untitled

a guest
Dec 8th, 2019
77
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