これは、UNIX システムでは些細なことです。共有メモリ関数を使用するだけです:
shgmet、shmat、shmctl、shmdt
void *shmat(int shmid, const void *shmaddr, int shmflg);
shmat() は、shmid によって識別される共有メモリ セグメントを、呼び出しプロセスのアドレス空間にアタッチします。接続アドレスは、次の基準のいずれかで shmaddr によって指定されます。
shmaddr が NULL の場合、システムはセグメントを接続する適切な (未使用の) アドレスを選択します。
ここで自分のアドレスを指定するだけです。例: 0x20000000000
すべてのプロセスで同じキーとサイズを使用して shmget() を実行すると、同じ共有メモリ セグメントが得られます。同じアドレスで shmat() を実行すると、仮想アドレスはすべてのプロセスで同じになります。カーネルは、通常割り当てられる場所と競合しない限り、使用するアドレス範囲を気にしません。(アドレスを省略すると、配置するのが好きな一般的な領域がわかります。また、スタック上のアドレスと malloc() / new[] から返されたアドレスを確認してください。)
Linux では、root が /proc/sys/kernel/shmmax の SHMMAX を、共有メモリ セグメントに対応できる十分な数に設定していることを確認してください (デフォルトは 32MB)。
アトミック操作に関しては、Linux カーネル ソースからすべて取得できます。
include/asm-x86/atomic_64.h
/*
* Make sure gcc doesn't try to be clever and move things around
* on us. We need to use _exactly_ the address the user gave us,
* not some alias that contains the same information.
*/
typedef struct {
int counter;
} atomic_t;
/**
* atomic_read - read atomic variable
* @v: pointer of type atomic_t
*
* Atomically reads the value of @v.
*/
#define atomic_read(v) ((v)->counter)
/**
* atomic_set - set atomic variable
* @v: pointer of type atomic_t
* @i: required value
*
* Atomically sets the value of @v to @i.
*/
#define atomic_set(v, i) (((v)->counter) = (i))
/**
* atomic_add - add integer to atomic variable
* @i: integer value to add
* @v: pointer of type atomic_t
*
* Atomically adds @i to @v.
*/
static inline void atomic_add(int i, atomic_t *v)
{
asm volatile(LOCK_PREFIX "addl %1,%0"
: "=m" (v->counter)
: "ir" (i), "m" (v->counter));
}
64 ビット版:
typedef struct {
long counter;
} atomic64_t;
/**
* atomic64_add - add integer to atomic64 variable
* @i: integer value to add
* @v: pointer to type atomic64_t
*
* Atomically adds @i to @v.
*/
static inline void atomic64_add(long i, atomic64_t *v)
{
asm volatile(LOCK_PREFIX "addq %1,%0"
: "=m" (v->counter)
: "er" (i), "m" (v->counter));
}