Macでは名前無しSemaphoreは未サポート

並行プログラムを勉強したくてMac OS X上でスレッドの同期をとる仕組みであるセマフォを勉強してみたので備忘録がてらブログを。

セマフォ(英語ではSemaphore)というのは複数のプロセスやスレッドが同期を取るための制御構造あるいは,そのような構造を構成する為のデータ型を指す。
この概念はグラフ構造のデータ上で最短パスを見つける為に使うアルゴリズムダイクストラ法を考案したエドガー・ダイクストラ氏が考案した。

データ型としてのセマフォ(以下単にセマフォと言ったらデータ型を指すとして)はPOSIXで提供されているのでLinuxUnixで使用する事ができる。
今回勉強するにあたって言語はC++コンパイラXCode付属の物を使ってみた。

sem_initを使ってみると

セマフォ変数の初期化関数であるsem_initを試すために次のようなサンプルコードをコンパイルしてみると

#include "semaphore.h"
int main(void) {
  sem_t value;
  if( sem_init( &value, 0, 0) == -1 ){
     perror("sem_init");
  }
  return 0;
}

こんなワーニングがでます。

 warning: 'sem_init' is deprecated [-Wdeprecated-declarations]
  if( sem_init( &value, 0, 1) == -1 ){
      ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/sys/semaphore.h:55:5: note: 
      'sem_init' has been explicitly marked deprecated here
int sem_init(sem_t *, int, unsigned int) __deprecated;

作成された実行ファイルを実行すると…

bash-3.2$ ./a.out 
sem_init: Function not implemented

エラーで止まってしまう。

理由は

sem_initは名前無しのセマフォ変数をメモリ内に作るがそもそもこれはXCodeコンパイラでは未サポートなのでワーニングでsem_initはやめようねと指摘されている。

名前無しセマフォとは同一プロセス内あるいは共有メモリを使っている複数プロセス間で使用されるものだ。

ところで、『名前無し』に対して『名前付きセマフォ』というのがあって、共有メモリを用いていない複数間のプロセスでも同期がとれるものだ。この名前付きセマフォを初期化するのにはsem_openという関数を呼び出す。


実はXCodeではセマフォを使うなら名前付きセマフォを用いないといけなくて、名前無しセマフォは未サポートだった。
ということで、

結論

Xcode使うならsem_openで名前付きセマフォを使おう。