AIX(と誰かが気にするHPUX)は、複数のプロセスで共有されているメモリマップファイルの細かい部分(たとえばレコード)を簡単に同期できるようにする、msemaphoresという素晴らしい機能があります。 Linuxに匹敵するものを誰かが知っていますか?msemaphore on linux?
明らかに、msemaphore関数は、関連リンクhereに従って記述されています。
AIX(と誰かが気にするHPUX)は、複数のプロセスで共有されているメモリマップファイルの細かい部分(たとえばレコード)を簡単に同期できるようにする、msemaphoresという素晴らしい機能があります。 Linuxに匹敵するものを誰かが知っていますか?msemaphore on linux?
明らかに、msemaphore関数は、関連リンクhereに従って記述されています。
Linuxでは、SysV共有メモリで必要なものを達成できます。クイックグーグルが助けになるかもしれないthis (rather old) guideとなった。
POSIX semaphoresは、sem_init(3)
の2番目の引数 "pshared
"がtrueの場合、プロセス間で共有されるメモリに配置できます。これはmsem
と同じであるようです。
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <time.h>
#include <unistd.h>
int main() {
void *shared;
sem_t *sem;
int counter, *data;
pid_t pid;
srand(time(NULL));
shared = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_SHARED, -1, 0);
sem_init(sem = shared, 1, 1);
data = shared + sizeof(sem_t);
counter = *data = 0;
pid = fork();
while (1) {
sem_wait(sem);
if (pid)
printf("ping>%d %d\n", data[0] = rand(), data[1] = rand());
else if (counter != data[0]) {
printf("pong<%d", counter = data[0]);
sleep(2);
printf(" %d\n", data[1]);
}
sem_post(sem);
if (pid) sleep(1);
}
}
これはかなりダムテストですが、それは動作します:
$ cc -o test -lrt test.c
$ ./test
ping>2098529942 315244699
pong<2098529942 315244699
pong<1195826161 424832009
ping>1195826161 424832009
pong<1858302907 1740879454
ping>1858302907 1740879454
ping>568318608 566229809
pong<568318608 566229809
ping>1469118213 999421338
pong<1469118213 999421338
ping>1247594672 1837310825
pong<1247594672 1837310825
ping>478016018 1861977274
pong<478016018 1861977274
ping>1022490459 935101133
pong<1022490459 935101133
...
セマフォは、2つのプロセス間で共有されているので、pong
sがにもかかわらず、ping
sからインターリーブされたデータを得ることはありませんsleep
s。
これは、POSIX共有メモリのミューテックスを使用して行うことができます。
pthread_mutexattr_t attr;
int pshared = PTHREAD_PROCESS_SHARED;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, &pshared);
pthread_mutex_init(&some_shared_mmap_structure.mutex, &attr);
pthread_mutexattr_destroy(&attr);
今、あなたは普通のpthread_mutex_lockのを使用して& some_shared_mmap_structure.mutexのロックを解除してロックできます()それがマッピングされてい複数のプロセスからなどのコールは、。 (未テスト)
struct msemaphore {
pthread_mutex_t mut;
};
#define MSEM_LOCKED 1
#define MSEM_UNLOCKED 0
#define MSEM_IF_NOWAIT 1
msemaphore *msem_init(msemaphore *msem_p, int initialvalue) {
pthread_mutex_attr_t attr;
int pshared = PTHREAD_PROCESS_SHARED;
assert((unsigned long)msem_p & 7 == 0); // check alignment
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, &pshared); // might fail, you should probably check
pthread_mutex_init(&msem_p->mut, &attr); // never fails
pthread_mutexattr_destroy(&attr);
if (initialvalue)
pthread_mutex_lock(&attr);
return msem_p;
}
int msem_remove(msemaphore *msem) {
return pthread_mutex_destroy(&msem->mut) ? -1 : 0;
}
int msem_lock(msemaphore *msem, int cond) {
int ret;
if (cond == MSEM_IF_NOWAIT)
ret = pthread_mutex_trylock(&msem->mut);
else
ret = pthread_mutex_lock(&msem->mut);
return ret ? -1 : 0;
}
int msem_unlock(msemaphore *msem, int cond) {
// pthreads does not allow us to directly ascertain whether there are
// waiters. However, a unlock/trylock with no contention is -very- fast
// using linux's pthreads implementation, so just do that instead if
// you care.
//
// nb, only fails if the mutex is not initialized
return pthread_mutex_unlock(&msem->mut) ? -1 : 0;
}
ありがとう:
確かに、あなたも、この面でmsemのAPIを実装することができます。 Msemaphoresは、自分で構築するのではなく、すでに実装されていたと思っていた便利さとシンプルさを提供します。 – Duck