私のタスクは、2つの異なるCファイルを作成してから、プロセスの同期にセマフォを使用することです(両方のCファイルを同時に実行します)。
私の主な関心事は、両方のプロセス(Cファイルの実行可能ファイル)のセマフォにアクセスする場合、共有メモリにセマフォを作成する必要があるということです。また、バイナリセマフォを作成する必要があります。
それは私の最初のプログラムなので、誰かがこれを始める方法を提案できますか?
スレッド内で共有メモリ、使用済みセマフォを作成して使用することができます。 YouTube の講義もいくつか見ましたが、適切な解決策が見つかりませんでした。
クロスプロセスセマフォは、オペレーティングシステム固有の操作です。
これらの共有のほとんどは、セマフォの名前としてダビングする仮想パスを介して、1つのプロセスでセマフォを作成することです。権限が正しく設定されている場合、同じ仮想パスを使用して、別のプロセスでセマフォを開くことができます。これらの仮想パスは、見慣れているように見えても、通常は実際のファイルシステムパスではありません。
POSIX/System Vベースのシステムでは、通常2つのオプションがあります。 2つのオプションの違いは、 この回答 で非常によく説明されています。
System Vセマフォ
これらは、 semget()
で取得できるパスベースのセマフォです。
_#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int sem;
int sem_id = 1;
key_t key;
key = ftok("/virtualpathtosemaphore", 1);
// create a new semaphore
sem = semget(key, 1, IPC_CREAT);
// use sem = semget(key, 1, 0); to attach to an existing semaphore
// flags also contain access rights, to take care to set them appropriately
// increment semaphore
struct sembuf semopinc = {
.sem_num = 0,
.sem_op = 1,
.sem_flg = 0
};
semop(sem, &semopinc, 1);
/* decrement semaphore, may block */
struct sembuf semopdec = {
.sem_num = 0,
.sem_op = -1,
.sem_flg = 0
};
semop(sem, &semopdec, 1);
_
System Vセマフォは明示的にリンクが解除されるまで存続するため、セマフォをクリーンアップすることが重要であることに注意してください。これは、プロセスがセマフォをクリーンアップせずにクラッシュした場合の一種の問題です(たとえば、FreeBSDにはユーティリティipcrm
do remove dangling System V IPCオブジェクト)が付属しています)。
POSIXセマフォ
これらは実際にはあまり広く実装されていないため、カーネルがそれらをサポートしているかどうかを確認してください。これらの名前付きバージョンは、 sem_open()
を介して取得されます。
_#include <semaphore.h>
sem_t *sem;
sem = sem_open("/nameofsemaphore", O_CREAT, permissions, 0);
// use sem = sem_open("/nameofsemaphore", 0) to open an existing semaphore
/* increment semaphore */
sem_post(sem);
/* decrement semaphore */
sem_wait(sem);
_
POSIXセマフォは、セマフォへのハンドルを持つ最後のプロセスが終了すると、暗黙的に破棄されます。それらはSystemVセマフォよりも速いと噂されています
Windows
Windowsには独自のセマフォAPIがあります。セマフォは CreateSemaphore()
によって作成されます。
Windowsは、POSIXと同じ命名トリックを使用しますが、名前空間の規則が異なります。
_HANDLE hSem;
hSem = CreateSemaphore(NULL, 0, LONG_MAX, _T("Local\\PathToMySemaphore");
// Use OpenSemaphore() to attach to an existing semaphore
// increment semaphore:
ReleaseSemaphore(hSem, 1, NULL);
// decrement semaphore
WaitForSingleObject(hSem, 0);
_
上記の例を適用するときは、エラーチェックを追加することを忘れないでください。また、コードを簡略化するために、アクセス許可を意図的に無視していることにも注意してください。関連するフラグを追加することを忘れないでください。
これらすべてに加えて、(実際のセマフォが到着する前に一般的に行われているように)バイナリミューテックスの形式としてファイルロックを悪用することもできます。
Ubuntu GNU/Linuxを使用しているとおっしゃっていたので、...
名前付きセマフォを使用してください!
#include <semaphore.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
// On first process (the one that creates the semaphore)
char semaphoreName[1 + 6 + 1];
semaphoreName[0] = '/';
semaphoreName[1 + snprintf(&semaphore[1], 6 + 1, "%d", getpid())] = '/0';
sem_t *sem = sem_open(semaphoreName, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 0);
// On second process
sem_t *sem = sem_open(semaphoreName, O_RDWR);