Advertisement
3axap_010

ThreadsSynchronization.c

Apr 30th, 2020
298
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.55 KB | None | 0 0
  1. #include <pthread.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include <termios.h>
  5. #include <stdlib.h>
  6.  
  7. static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  8.  
  9. void* thread_routine(void* args)
  10. {
  11.     while (1)
  12.     {
  13.         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
  14.  
  15.         pthread_mutex_lock(&mutex);
  16.         fprintf(stdout, "%s\n", (char*)args);
  17.         pthread_mutex_unlock(&mutex);
  18.  
  19.         pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
  20.         usleep(100);
  21.     }
  22.  
  23.     pthread_exit(NULL);
  24. }
  25.  
  26. struct stack
  27. {
  28.     pthread_t thread;
  29.     char* thread_output_string;
  30.     struct stack* next;
  31. };
  32.  
  33. void push(struct stack** head, pthread_t thread, char* thread_output_string)
  34. {
  35.     struct stack* s = malloc(sizeof(struct stack));
  36.     s->next = *head;
  37.     s->thread_output_string = thread_output_string;
  38.     s->thread = thread;
  39.     *head = s;
  40. }
  41.  
  42. int empty(struct stack* head)
  43. {
  44.     return head == NULL;
  45. }
  46.  
  47. pthread_t pop(struct stack** head)
  48. {
  49.     if (empty(*head))
  50.     {
  51.         return -1;
  52.     }
  53.  
  54.     struct stack* temp = *head;
  55.     *head = temp->next;
  56.     pthread_t thread = temp->thread;
  57.     free(temp->thread_output_string);
  58.     free(temp);
  59.  
  60.     return thread;
  61. }
  62.  
  63. char* get_thread_string(int threads_count)
  64. {
  65.     int lenght = snprintf(NULL, 0, "%d", threads_count);
  66.  
  67.     char* output_string = malloc(sizeof(char) * (lenght + 1));
  68.     sprintf(output_string, "%d", threads_count);
  69.     output_string[lenght] = '\0';
  70.  
  71.     return output_string;
  72. }
  73.  
  74. void create_thread(struct stack** head, int threads_count)
  75. {
  76.     pthread_t thread;
  77.     char* thread_output_string = get_thread_string(threads_count);
  78.     pthread_create(&thread, NULL, thread_routine, (void*)thread_output_string);
  79.     push(head, thread, thread_output_string);
  80. }
  81.  
  82. int terminate_thread(struct stack** head)
  83. {
  84.     pthread_t thread;
  85.     if ((thread = pop(head)) == -1)
  86.     {
  87.         return 0;
  88.     }
  89.  
  90.     pthread_cancel(thread);
  91.  
  92.     return 1;
  93. }
  94.  
  95. /* reads from keypress, doesn't echo */
  96. int getch(void)
  97. {
  98.     struct termios oldattr, newattr;
  99.     int ch;
  100.     tcgetattr( STDIN_FILENO, &oldattr );
  101.     newattr = oldattr;
  102.     newattr.c_lflag &= ~( ICANON | ECHO );
  103.     tcsetattr( STDIN_FILENO, TCSANOW, &newattr );
  104.     ch = getchar();
  105.     tcsetattr( STDIN_FILENO, TCSANOW, &oldattr );
  106.     return ch;
  107. }
  108.  
  109. int main()
  110. {
  111.     struct stack* head = NULL;
  112.     int threads_count = 0;
  113.     char c;
  114.  
  115.     while ((c = getch()) != 'q')
  116.     {
  117.         switch (c)
  118.         {
  119.         case '+':
  120.             create_thread(&head, ++threads_count);
  121.             break;
  122.         case '-':
  123.             terminate_thread(&head);
  124.             break;
  125.         default:
  126.             break;
  127.         }
  128.     }
  129.  
  130.     while (terminate_thread(&head))
  131.         ;
  132.  
  133.     pthread_mutex_destroy(&mutex);
  134.  
  135.     exit(EXIT_SUCCESS);
  136. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement