ホームページ  >  記事  >  システムチュートリアル  >  Linux IPC System V 共有メモリ: 高速データ交換への先進的なアプローチ

Linux IPC System V 共有メモリ: 高速データ交換への先進的なアプローチ

WBOY
WBOY転載
2024-02-13 08:30:321212ブラウズ

Linux システムは、マルチタスクの同時実行をサポートするオペレーティング システムであり、複数のプロセスを同時に実行できるため、システムの使用率と効率が向上します。ただし、これらのプロセス間でデータ交換とコラボレーションが必要な場合は、シグナル、メッセージ キュー、セマフォなどのプロセス間通信 (IPC) メソッドを使用する必要があります。その中でも、System V 共有メモリは、データのコピーや変換を必要とせずに、2 つ以上のプロセスがメモリ領域を介してデータを交換できる、比較的先進的で高速な IPC 方式です。この記事では、共有メモリの作成、マッピング、読み取り、書き込み、マッピング解除、削除など、Linux システムでの System V 共有メモリの方法を紹介します。

Linux IPC System V 共享内存:一种实现高速数据交换的高级方式

######モデル###### リーリー

ftok()

リーリー

pathname: ファイル名

proj_id: project_id を表す 1 ~ 255 の数字 リーリー
shmget()

リーリー

key: ftok()の戻り値

size: 実際の共有メモリのサイズはページサイズ(PAGE_SIZE)に応じて割り当てられます。 0は、割り当てられた共有メモリを取得することを意味します
shmflg: 特定の操作フラグ
IPC_CREAT

: 存在しない場合は作成します。shmflg に「|権限情報」を設定する必要があります (例: |0664; 存在する場合は開きます
  • IPC_EXCL: IPC_CREAT と組み合わせて使用​​されます。存在する場合、作成は失敗します ==> エラーが報告され、errno
  • を設定します 0: 既存の共有メモリを取得します
  • rree Q
  • : shmget() は作成できるので、ftok() は何に役立ちますか

A: shmget は共有メモリの作成に使用され、ftok() はのみ使用されます実際にはキーの位置に数字を入力して実行することもできますが、システムが生成するものと比べて競合が発生しやすいため、ftokを使用して生成することをお勧めしますかぎ###
shmat() リーリー

shmid: shmget()の戻り値

shmaddr


NULL はシステムによって選択されたことを意味します (mmap() と同じ)

NULL ではなく、shflg が SHM_RND の場合、shmaddr から始まる最も近いアドレスを検索し、ページ アラインメントの原則に従ってポイントの割り当てを開始します。それ以外の場合、shmaddr で指定されたアドレスはページ アラインメントである必要があります。
    shmflg: 操作のフラグ。0 を指定してください。
  • SHM_RDONLY
  • 共有メモリに接続されているプロセスには読み取り権限が必要であることを示します
    • SHM_REMAP
    • (Linux 固有) は、マップされる共有メモリにすでに既存のメモリがある場合、古いメモリを置き換えることを意味します
    • rree shmdt()
    リーリー
  • shmctl()

リーリー shmid

: shmget() によって返される共有メモリの ID

buf: shmid_ds

型のポインター リーリー

cmd

  • IPC_STAT表示从内核中拷贝关于这个shmid的信息到buf指向的shmid_ds中

  • IPC_SET 将buf指向的shmid_ds的信息写入到内核的结构体中,同时更新成员shm_ctime

  • IPC_RMID销毁共享内存

  • IPC_INFO(Linux-specific)返回系统对共享内存的限制写入到buf指向的时shminfo结构体中

    //_GNU_SOURCE
    struct  shminfo {
        unsigned long   shmmax; /* Maximum segment size */
        unsigned long   shmmin; /* Minimum segment size; always 1 */
        unsigned long   shmmni; /* Maximum number of segments */
        unsigned long   shmseg; /* Maximum number of segments that a process 
    can attach; unused within kernel */
        unsigned long   shmall; /* Maximum number of pages of shared memory, 
    system-wide */
     };
     //shmmni, shmmax, and shmall 可以童工/proc里的同名文件进行修改
    
  • SHM_INFO(Linux-specific) 返回一个shm_info结构体来表示该共享内存消耗的系统资源

    //_GNU_SOURCE
    struct shm_info {
        int             used_ids;   /* # of currently existing segments */
        unsigned long   shm_tot;    /* Total number of shared memory pages */
        unsigned long   shm_rss;    /* # of resident shared memory pages */
        unsigned long   shm_swp;    /* # of swapped shared memory pages */
        unsigned long   swap_attempts; /* Unused since Linux 2.4 */
        unsigned long   swap_successes;/* Unused since Linux 2.4 */
     };
    
  • SHM_STAT(Linux-specific) 为IPC_STAT返回一个shmid_ds结构结构体,不同的是shmid的参数不是一个标识符,而是内核中一个包含了系统中所有共享内存信息的索引

  • SHM_LOCK防止系统将共享内存放到swap区,IPC_STAT读到的信息中SHM_LOCKED标记就被设置了

  • SHM_UNLOCK 解除锁定,即允许共享内存被系统放到swap区

//使用IPC_RMID删除共享内存
int res=shmctl(shmid,IPC_RMID,NULL);
if(-1==res)
    perror("shmctl"),exit(-1);

例子

//Sys V IPC shm
int shmid;          //定义全局变量记录id
void fa(int signo){
    printf("deleting shared memories...\n");
    sleep(3);//其实没用
    int res=shmctl(shmid,IPC_RMID,NULL);
    if(-1==res)
        perror("shmctl"),exit(-1);
    printf("delete success\n");
    exit(0);    //ctrl+C已经不能结束while(1),用exit(0)来终结
}
int main(){
    //获取key
    key_t key=ftok(".",100);    //.就是一个存在且可访问的路径, 100是随便给的
    if(-1==key)
        perror("ftok"),exit(-1);
    printf("key=%#x\n",key);    //打印出进制的标示,即0x
    //创建shared memory
    shmid=shmget(key,4,IPC_CREAT|IPC_EXCL|0664);
    if(-1==shmid)
        perror("shmget"),exit(-1);
    printf("shmid=%d\n",shmid);
    //挂接shm
    void* pv=shmat(shmid,NULL,0);
    if((void*)-1==pv)
        perror("shmat"),exit(-1);
    printf("link shared memory success\n");
    //访问shm
    int* pi=(int*)pv;
    *pi=100;
    //脱接shm
    int res=shmdt(pv);
    if(-1==res)
        perror("shmdt"),exit(-1);
    printf("unlink success\n");
    //如果不再使用,删除shm
    printf("删除共享内存请按Ctrl C...\n");
    if(SIG_ERR==signal(SIGINT,fa))
        perror("signal"),exit(-1);
    while(1);
    return 0;
}

本文介绍了Linux系统中System V 共享内存的方法,包括共享内存的创建、映射、读写、解除映射和删除等方面。通过了解和掌握这些知识,我们可以更好地使用System V 共享内存来实现进程间通信,提高系统的性能和可靠性。当然,Linux系统中System V 共享内存还有很多其他的特性和用法,需要我们不断地学习和探索。希望本文能给你带来一些启发和帮助。

以上がLinux IPC System V 共有メモリ: 高速データ交換への先進的なアプローチの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はlxlinux.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。