GNU/Linux >> Linux の 問題 >  >> Linux

Linux in C で共有メモリを使用する方法

以下は共有メモリの例です:

#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 つのアプローチがあります: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);
      }
    }
    

    Linux
    1. LinuxでSuコマンドを使用する方法

    2. 例を使用してLinuxでRmmodコマンドを使用する方法

    3. LinuxでVmstatコマンドを使用する方法を例で説明します

    1. libvirtでVagrantを使用する方法

    2. LinuxでBusyBoxを使用する方法

    3. Linux で UID 0 の非ルート ユーザーを削除する方法

    1. Linuxでcronを使用する方法

    2. 実用的な例でLinuxHexdumpコマンドを使用する方法

    3. LinuxでのSCPコマンド:使用方法と例