セマフォを確実に回復する方法がないことが判明しました。もちろん、誰でも post_sem()
できます 名前付きセマフォに対して、カウントが再びゼロを超えて増加するようにしますが、そのような回復が必要な場合はどうすればわかりますか?提供された API は限定的すぎて、これがいつ発生したかを示すものではありません。
利用可能な ipc ツールにも注意してください -- 一般的なツール ipcmk
、 ipcrm
、および ipcs
古い SysV セマフォ専用です。特に、新しい POSIX セマフォでは機能しません。
しかし、シグナルハンドラでキャッチできない方法でアプリケーションが終了すると、オペレーティングシステムが自動的に解放するものをロックするために使用できるものは他にもあるようです。 2 つの例:特定のポートにバインドされたリッスン ソケット、または特定のファイルのロック。
ファイルのロックが必要な解決策であると判断しました。 sem_wait()
の代わりに および sem_post()
呼び出し、使用しています:
lockf( fd, F_LOCK, 0 )
そして
lockf( fd, F_ULOCK, 0 )
アプリケーションが何らかの方法で終了すると、ファイルは自動的に閉じられ、ファイル ロックも解除されます。 「セマフォ」を待機している他のクライアント アプリは、期待どおりに自由に続行できます。
皆さん、助けてくれてありがとう。
@Stéphaneのソリューションによく似ていますが、 flock() 呼び出しなしで、セマフォの代わりにロックファイルを使用します。排他ロックを使用してファイルを開くことができます:
//call to open() will block until it can obtain an exclusive lock on the file.
errno = 0;
int fd = open("/tmp/.lockfile",
O_CREAT | //create the file if it's not present.
O_WRONLY | //only need write access for the internal locking semantics.
O_EXLOCK, //use an exclusive lock when opening the file.
S_IRUSR | S_IWUSR); //permissions on the file, 600 here.
if (fd == -1) {
perror("open() failed");
exit(EXIT_FAILURE);
}
printf("Entered critical section.\n);
//Do "critical" stuff here.
//exit the critical section
errno = 0;
if (close(fd) == -1) {
perror("close() failed");
exit(EXIT_FAILURE);
}
printf("Exited critical section.\n");
これは、セマフォを管理する際の典型的な問題です。一部のプログラムは、単一のプロセスを使用してセマフォの初期化/削除を管理します。通常、このプロセスはこれだけを行い、他には何もしません。他のアプリケーションは、セマフォが使用可能になるまで待機できます。これは SYSV タイプの API で行われるのを見たことがありますが、POSIX では行われません。 「アヒル」に似ています semop() 呼び出しで SEM_UNDO フラグを使用して言及しました。
でも あなたが提供した情報では、セマフォを使用しないことをお勧めします。特に、プロセスが強制終了またはクラッシュの危険にさらされている場合。 OS が自動的にクリーンアップするものを使用してみてください。