以下は共有メモリの例です:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define SHM_SIZE 1024 /* make it a 1K shared memory segment */
int main(int argc, char *argv[])
{
key_t key;
int shmid;
char *data;
int mode;
if (argc > 2) {
fprintf(stderr, "usage: shmdemo [data_to_write]\n");
exit(1);
}
/* make the key: */
if ((key = ftok("hello.txt", 'R')) == -1) /*Here the file must exist */
{
perror("ftok");
exit(1);
}
/* create the segment: */
if ((shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT)) == -1) {
perror("shmget");
exit(1);
}
/* attach to the segment to get a pointer to it: */
if ((data = shmat(shmid, NULL, 0)) == (void *)-1) {
perror("shmat");
exit(1);
}
/* read or modify the segment, based on the command line: */
if (argc == 2) {
printf("writing to segment: \"%s\"\n", argv[1]);
strncpy(data, argv[1], SHM_SIZE);
} else
printf("segment contains: \"%s\"\n", data);
/* detach from the segment: */
if (shmdt(data) == -1) {
perror("shmdt");
exit(1);
}
return 0;
}
手順:
<オール>ftok を使用して、パス名とプロジェクト ID を System V IPC キーに変換します
共有メモリ セグメントを割り当てる shmget を使用します
shmat を使用して、shmid によって識別される共有メモリ セグメントを呼び出しプロセスのアドレス空間にアタッチします
メモリ領域で操作を行います
shmdt を使用してデタッチ
2 つのアプローチがあります:shmget
と mmap
. mmap
について話します 、よりモダンで柔軟なので、 man shmget
を見ることができます (またはこのチュートリアル) 古いスタイルのツールを使用したい場合。
mmap()
関数を使用して、高度にカスタマイズ可能なパラメーターを使用してメモリ バッファーを割り当て、アクセスとアクセス許可を制御し、必要に応じてファイル システム ストレージでバックアップすることができます。
次の関数は、プロセスがその子プロセスと共有できるメモリ内バッファを作成します:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
void* create_shared_memory(size_t size) {
// Our memory buffer will be readable and writable:
int protection = PROT_READ | PROT_WRITE;
// The buffer will be shared (meaning other processes can access it), but
// anonymous (meaning third-party processes cannot obtain an address for it),
// so only this process and its children will be able to use it:
int visibility = MAP_SHARED | MAP_ANONYMOUS;
// The remaining parameters to `mmap()` are not important for this use case,
// but the manpage for `mmap` explains their purpose.
return mmap(NULL, size, protection, visibility, -1, 0);
}
以下は、上記で定義した関数を使用してバッファを割り当てるプログラムの例です。親プロセスはメッセージを書き込み、フォークし、子がバッファを変更するのを待ちます。両方のプロセスが共有メモリを読み書きできます。
#include <string.h>
#include <unistd.h>
int main() {
char parent_message[] = "hello"; // parent process will write this message
char child_message[] = "goodbye"; // child process will then write this one
void* shmem = create_shared_memory(128);
memcpy(shmem, parent_message, sizeof(parent_message));
int pid = fork();
if (pid == 0) {
printf("Child read: %s\n", shmem);
memcpy(shmem, child_message, sizeof(child_message));
printf("Child wrote: %s\n", shmem);
} else {
printf("Parent read: %s\n", shmem);
sleep(1);
printf("After 1s, parent read: %s\n", shmem);
}
}