»POSIX Semaphoreはてなブックマークに追加はてなブックマークを見る

»POSIX Semaphore

»使用例

// gcc -pthread -std=c99

#include <stdio.h>
#include <semaphore.h>
#include <fcntl.h>
#include <sys/types.h> 
#include <sys/wait.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>


// セマフォに与える名前
#define SEMAPHORE_NAME ("/interproc_semaphore_sample")

// 生成する子プロセス数
#define CHILD_MAX (10)

// セマフォオブジェクト
sem_t* semaphore = NULL;


//
// ミリ秒単位のsleep
//
int msleep( int milliseconds )
{
  struct timespec t;

  t.tv_sec  =   milliseconds / 1000;
  t.tv_nsec = ( milliseconds % 1000 ) * 1000000;

  return nanosleep( &t, NULL );
}


//
// 子プロセスの処理
//
void child_main()
{
  pid_t pid = getpid();
  int semval = 0;

  printf( "ProcessID %d, started\n", pid );

  // セマフォのカウンタを表示する
  sem_getvalue( semaphore, &semval );

  printf( "->semaphore count: %d\n", semval );

  printf( "ProcessID %d, wait for  semaphore\n", pid );

  // セマフォに入る
  sem_wait( semaphore );

  printf( "ProcessID %d, access to semaphore\n", pid );

  // 適当な時間だけ待ち合わせる
  msleep( 1500 );

  printf( "ProcessID %d, release   semaphore\n", pid );

  // セマフォを出る
  sem_post( semaphore );

  // セマフォのカウンタを表示する
  sem_getvalue( semaphore, &semval );

  printf( "->semaphore count: %d\n", semval );

  printf( "ProcessID %d, exited\n", pid );
}


//
// 親プロセス
//
int main( void )
{
  // 初期値3のセマフォを作成する
  // (すでに同名のセマフォが存在する場合は、modeとvalueは無視される)
  semaphore = sem_open( SEMAPHORE_NAME, O_CREAT | O_EXCL, 0777, 3 );

  printf( "semaphore created\n" );

  // 250ミリ秒おきに子プロセスを生成する
  for ( int count = 0; count < CHILD_MAX; count++ )
  {
    pid_t pid = fork();

    if ( 0 == pid )
    {
      // 子プロセスの処理を開始する
      child_main();

      _exit( 0 );
    }
    else if ( -1 == pid )
    {
      printf( "fork failed\n" );

      return 1;
    }

    msleep( 300 );
  }

  // すべての子プロセスの終了を待機する
  for ( int count = 0; count < CHILD_MAX; )
  {
    int status;
    pid_t pid;

    pid = waitpid( -1, &status, WNOHANG );

    if( 0 < pid )
    {
      // 子プロセスが終了した
      count++;

      continue;
    }
    else if ( -1 == pid )
    {
      break;
    }

    // 500ミリ秒おきに子プロセスの状態を監視する
    msleep( 500 );
  }

  printf( "all processes are finished\n" );

  // セマフォを破棄する
  sem_close( semaphore );

  printf( "semaphore closed\n" );

  // セマフォを削除する
  sem_unlink( SEMAPHORE_NAME );

  printf( "semaphore unlinked\n" );

  return 0;
}

実行例。

semaphore created
ProcessID 7862, started
->semaphore count: 3
ProcessID 7862, wait for  semaphore
ProcessID 7862, access to semaphore
ProcessID 7863, started
->semaphore count: 2
ProcessID 7863, wait for  semaphore
ProcessID 7863, access to semaphore
ProcessID 7864, started
->semaphore count: 1
ProcessID 7864, wait for  semaphore
ProcessID 7864, access to semaphore
ProcessID 7865, started
->semaphore count: 0
ProcessID 7865, wait for  semaphore
ProcessID 7866, started
->semaphore count: 0
ProcessID 7866, wait for  semaphore
ProcessID 7862, release   semaphore
ProcessID 7865, access to semaphore
->semaphore count: 0
ProcessID 7862, exited
ProcessID 7867, started
->semaphore count: 0
ProcessID 7867, wait for  semaphore
ProcessID 7863, release   semaphore
->semaphore count: 1
ProcessID 7863, exited
ProcessID 7866, access to semaphore
ProcessID 7868, started
->semaphore count: 0
ProcessID 7868, wait for  semaphore
ProcessID 7864, release   semaphore
->semaphore count: 1
ProcessID 7864, exited
ProcessID 7867, access to semaphore
ProcessID 7869, started
->semaphore count: 0
ProcessID 7869, wait for  semaphore
ProcessID 7870, started
->semaphore count: 0
ProcessID 7870, wait for  semaphore
ProcessID 7871, started
->semaphore count: 0
ProcessID 7871, wait for  semaphore
ProcessID 7865, release   semaphore
->semaphore count: 1
ProcessID 7865, exited
ProcessID 7868, access to semaphore
ProcessID 7866, release   semaphore
->semaphore count: 1
ProcessID 7866, exited
ProcessID 7869, access to semaphore
ProcessID 7867, release   semaphore
->semaphore count: 1
ProcessID 7867, exited
ProcessID 7870, access to semaphore
ProcessID 7868, release   semaphore
->semaphore count: 1
ProcessID 7868, exited
ProcessID 7871, access to semaphore
ProcessID 7869, release   semaphore
->semaphore count: 1
ProcessID 7869, exited
ProcessID 7870, release   semaphore
->semaphore count: 2
ProcessID 7870, exited
ProcessID 7871, release   semaphore
->semaphore count: 3
ProcessID 7871, exited
all processes are finished
semaphore closed
semaphore unlinked

Sponsored Link