1. ホーム
  2. c

[解決済み] Linuxで共有メモリを使用する方法(C言語

2022-05-10 06:37:46

質問

あるプロジェクトでちょっとした問題があります。

での共有メモリの使用について、きちんと文書化された例を見つけようとしています。 fork() が、うまくいきません。

基本的にシナリオは、ユーザーがプログラムを開始したときに、私は共有メモリに2つの値を格納する必要があるということです。 カレントパス というもので、これは char* ファイル名 であり、これも char* .

コマンドの引数に応じて、新しいプロセスがキックオフされ fork() を読み込んで変更する必要があります。 カレントパス という変数が共有メモリに格納され、その間に ファイル名 変数は読み取り専用です。

共有メモリに関する良いチュートリアルで、サンプルコード(可能であれば)があるものはありますか?

どのように解決するのですか?

2つのアプローチがあります。 shmgetmmap . についてお話します。 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);
  }
}