2013年4月29日月曜日

[C言語]semaphore

複数のスレッドを生成した場合に semaphore を使用して動作の順番を制御する。
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

#define USE_SEMAPHORE 1
sem_t sem;

void *thread_func(void *param)
{
 int pid;
 int i;
 pthread_t thread_id;

#if USE_SEMAPHORE
 sem_wait(&sem);
#endif
 thread_id = pthread_self();
 printf("%s called\n", __FUNCTION__);
 printf("  thread ID = %ld\n", thread_id);
 printf("  2:pid = %d\n", pid);
 pid = getpid();
 sleep(5);
 printf("  done\n");
#if USE_SEMAPHORE
 sem_post(&sem);
#endif
}

#define THREAD_NUM_MAX 3
int main(void)
{
 pthread_t t[THREAD_NUM_MAX];
 int pid;
 int i;

#if USE_SEMAPHORE
 sem_init(&sem, 0, 1);
#endif

 pid = getpid();
 printf("1:pid = %d\n", pid);
 for (i = 0; i < THREAD_NUM_MAX; i++) {
  if (pthread_create(&t[i], NULL, thread_func, NULL) != 0) {
   printf("Failed pthread_create()\n");
   return -1;
  }
  printf("Next line of pthread_create() called. thead ID[%d] = %ld\n", i, t[i]);
 }

 for (i = 0; i < THREAD_NUM_MAX; i++) {
  pthread_join(t[i], NULL);
 }

#if USE_SEMAPHORE
 sem_destroy(&sem);
#endif

 printf("End of the program\n");

 return 0;
}
USE_SEMAPHORE を 0 にして semaphore を使用しなかった場合の出力結果
1:pid = 920
Next line of pthread_create() called. thead ID[0] = 7078224
thread_func called
  thread ID = 7078224
  2:pid = 7078224
thread_func called
Next line of pthread_create() called. thead ID[1] = 7078408
  thread ID = 7078408
  2:pid = 7078408
thread_func called
  thread ID = 7078544
  2:pid = 7078544
Next line of pthread_create() called. thead ID[2] = 7078544
  done
  done
  done
End of the program
3 つの子スレッドが同時に動作しているので全て sleep(5) を完了させて同時に終わる。
よって time コマンドでプログラムの実行時間を計測すると以下のように約 5 秒で終了している。
real    0m5.156s
user    0m0.405s
sys     0m0.015s
USE_SEMAPHORE を 1 にして semaphore を使用した場合の出力結果
1:pid = 1212
Next line of pthread_create() called. thead ID[0] = 7078256
thread_func called
  thread ID = 7078256
  2:pid = 7078256
Next line of pthread_create() called. thead ID[1] = 7078440
Next line of pthread_create() called. thead ID[2] = 7078576
  done
thread_func called
  thread ID = 7078440
  2:pid = 7078440
  done
thread_func called
  thread ID = 7078576
  2:pid = 7078576
  done
End of the program
1 つの semaphore を順番に取得 (wait/post) して動作しているので、3 つの子スレッドが順番に動作している。
time コマンドで実行時間を計測すると以下のように約 15 秒かかる。
real    0m15.203s
user    0m0.155s
sys     0m0.015s

0 件のコメント:

コメントを投稿