信号量と反発量C言語例理解スレッド同期

5109 ワード

スレッド同期
スレッド信号量の基礎知識を理解することはpythonのスレッドを深く理解するのに役立ちます.
2つのスレッドが同時に実行されると、同じ変数やファイルなどを同時に操作することは避けられないので、信号量と反発量を正確に実行できるメカニズムのセットが必要です.信号量は、最も単純な「バイナリ信号量」と、より一般的な「カウント信号量」に分けることができる.信号量は、通常、1つの実行スレッドによってのみ実行されるようにコードを保護するために使用され、この場合、バイナリ信号量を使用する必要がある.限られた数のスレッドが指定されたコードを実行することを許可することが望ましい場合があります.これは、カウント信号量を使用する必要があります.実際、技術信号量はバイナリ信号量の論理拡張であり、実際には両者が呼び出す関数と同じである.
反発量は信号量とよく似ていて、実際にはお互いに相手を通じて実現することができます.しかし、実際の応用では、いくつかの状況で1つを使用すると、より意味に合致し、より効果的です.
信号量で同期する
#include 
#include 
#include 
#include 
#include 
#include 

void *thread_function(void *arg);
sem_t bin_sem;

#define WORK_SIZE 1024
char work_area[WORK_SIZE];      /*          */

int main() {
  int res;                    /*             */
  pthread_t a_thread;         /*         */
  void *thread_result;       /*          */

  res = sem_init(&bin_sem, 0, 0);   /*       ,        0*/
  if (res != 0) {
    perror("Semaphore initialization failed");
    exit(EXIT_FAILURE);
  }
  res = pthread_create(&a_thread, NULL, thread_function, NULL);   /*       */
  if (res != 0) {
    perror("Thread creation failed");
    exit(EXIT_FAILURE);
  }
  printf("Inout some text, Enter 'end' to finish
"); while(strncmp("end", work_area, 3) != 0) { /* end ...*/ fgets(work_area, WORK_SIZE, stdin); /* worl_area */ sem_post(&bin_sem); /* +1 */ } printf("
Waiting for thread to finish...
"); res = pthread_join(a_thread, &thread_result); /* */ if (res != 0) { perror("Thread join failed"); exit(EXIT_FAILURE); } printf("Thread joined
"); sem_destroy(&bin_sem); /* */ exit(EXIT_SUCCESS); } void *thread_function(void *arg) { sem_wait(&bin_sem); /* 0 -1 */ while(strncmp("end", work_area, 3) != 0) { printf("You input %ld characters
", strlen(work_area)-1); /* 8*/ sem_wait(&bin_sem); /* 0 -1 */ } pthread_exit(NULL); }

はんぱつりょうで同期する
#include 
#include 
#include 
#include 
#include 
#include 

void *thread_function(void *arg);
pthread_mutex_t work_mutex;

#define WORK_SIZE 1024
char work_area[WORK_SIZE];
int time_to_exit = 0;                           /*         */

int main() {
  int res;
  pthread_t a_thread;
  void *thread_result;

  res = pthread_mutex_init(&work_mutex,NULL);    /*          */
  if (res != 0) {
    perror("Mutex initialization failed");
    exit(EXIT_FAILURE);
  }
  res = pthread_create(&a_thread, NULL, thread_function, NULL);  /*         */
  if (res != 0) {
    perror("Thread creation failed");
    exit(EXIT_FAILURE);
  }
  pthread_mutex_lock(&work_mutex);                       /*          */
  printf("Input some text, Enter 'end' to finish
"); while(!time_to_exit) { /* */ fgets(work_area, WORK_SIZE, stdin); /* work_area */ pthread_mutex_unlock(&work_mutex); /* */ while(1) { pthread_mutex_lock(&work_mutex); if (work_area[0] != '\0') { /* work_area , , , work_area*/ pthread_mutex_unlock(&work_mutex); sleep(1); } else { break; } } } pthread_mutex_unlock(&work_mutex); printf("
Waiting for thread to finish...
"); res = pthread_join(a_thread, &thread_result); if (res != 0) { perror("Thread join failed"); exit(EXIT_FAILURE); } printf("Thread joined
"); pthread_mutex_destroy(&work_mutex); exit(EXIT_SUCCESS); } void *thread_function(void *arg) { sleep(1); pthread_mutex_lock(&work_mutex); /* */ while(strncmp("end", work_area, 3) != 0) { /* work_area end */ printf("You input %ld characters
", strlen(work_area) -1); /* */ work_area[0] = '\0'; /* work_area */ pthread_mutex_unlock(&work_mutex); sleep(1); pthread_mutex_lock(&work_mutex); while (work_area[0] == '\0') { /* work_area */ pthread_mutex_unlock(&work_mutex); sleep(1); pthread_mutex_lock(&work_mutex); } } time_to_exit = 1; /* end , */ work_area[0] = '\0'; pthread_mutex_unlock(&work_mutex); pthread_exit(0); }

参考資料
  • 《Beginning Linux Programming》