Linuxプロセスの標準IPC共有メモリとの間に第四講義通信

ディレクトリ

第四に、標準のIPC

4.1共有メモリ

4.1.1概念と原則

4.1.2使用


第四に、標準のIPC

IPCは、すべてのIPCが持ってまとめ、実際には、と呼ばれる規格が標準IPC(プロセス間通信)を指定した以下のようなものであり、同一の規格の一部を有します

標準IPCは、前記共有メモリセマフォメッセージキューセット

普遍的な標準IPC仕様(上:ユーザー:カーネル)、以下のように:

(1)すべての標準IPCは一意の識別子として内部IDを有します

(2)内部IDを取得し  あなたは、外部キー、タイプkey_tのを必要とします

(3)の方法は次の3つの方法でキーを取得するには:

        1、キーとしてマクロIPC_PRIVATEを使用しますが、この方法は、外を得ることができない、基本的な必要性そう

        2、コード内のすべてのキーをカスタマイズ

        3、キーを取得するにはftok()関数を使用して、

#include <sys/types.h>
#include <sys/ipc.h>

key_t ftok(const char *pathname, int proj_id);

             パラメータ:

                    パス名 - パス(有効で/または必要があります。)

                    PROJ_ID - エンジニアリングID(非8ビットのデータが文字に、典型的には0です)

                    成功したリターンキー、戻るに失敗-1

 

(4)が丁度キーによって取得することがIDを取得)たshmget()msgget(:、一般に使用される関数が呼び出されるxxxget()、たとえば

(5)xxxctl()と呼ばれる特定の標準IPC機能を提供し、この機能は、少なくとも次の機能を含みます

         CMDを制御するパラメータの関数により、

            クエリ ------- IPC_STAT

            削除 ------- IPC_RMID    

            修正 ------- IPC_SET

(6)IPC標準共通コマンド

        IPCS - クエリシステムの現在の標準的なIPC構造

        ipcrm - 現在のシステムに(IDを通じて削除)標準IPC構造を削除

            オプション:

                  -aすべてのIPC構造

                  -m共有メモリ

                  -qメッセージキュー

                  -sセマフォ集合

          プロセスのマウントnattch数

 

4.1共有メモリ

4.1.1概念と原則

前に述べたように、共有メモリは標準IPC、そのおおよその標準の一つであります

その原理は、そのシステムをとる物理メモリを、媒体としてシステムカーネル(MMU)を管理する責任があり、この物理メモリマッピングのすべてのプロセスなので、異なるプロセスは、物理メモリの同じ部分にアクセスすることができる可能にする、データを有効にします交互に

高速なメモリアクセスなので、共有メモリは、最も効率的なIPCです

、(追加的な保護メカニズムを必要とするが、物理メモリの複数のプロセスが読み取りと書き込みのデータが原因の混乱に思われるセマフォセットを使用して

 

4.1.2使用

    1)キーを取得 ftokにより、機能を

    2)たshmget(によって)取得/共有メモリを作成します

          

          パラメータ:

                キー - 撮影した重要なステップ

                サイズ - 共有メモリ(有効作成)の大きさ

                shmflg - (実効を作成する場合)IDとアクセス権を作成します

                IPC_CREAT | 0666

                成功したリターンIDの共有メモリ、返すために失敗-1

    3)にshmat()によってマッピング/共有メモリが搭載され

          

         パラメータ:

               shmidを - 共有メモリID

               shmaddr - (NULLにシステムが選択した)ターゲットアドレスのマッピング

               shmflg - (読み取り専用ためSHM_RDONLY典型的には0に)マッピング識別子

               成功リターンマッピング先アドレス 1 -復帰に失敗した、(void *型)

    共有メモリ4)使用

    5)にshmdt終了()を使用してマッピングされていない/共有メモリを解放しました

         

    6)あなたの場合など、単にマウント、共有メモリプラス削除マークを削除するには、共有メモリ(共有メモリを削除するには、もはや使用、使用shmctl)が時に数0削除されていません

        

        パラメータ:

              shmidを - 共有メモリID

              CMD - コマンド

                    IPC_RMID:削除

                    IPC_SET:修正

                    IPC_STAT:GET

              着信設定/ UID、GIDとモードが変更することができ、そのデータ・タイプは、次の、共有メモリ情報から/までの時間を取得 - BUF

              shmctl関数成功時に0を返し、返しの失敗 -

struct shmid_ds {
               struct ipc_perm shm_perm;    /* Ownership and permissions */
               size_t          shm_segsz;   /* 大小 */
               time_t          shm_atime;   /* 最后挂载(映射)时间*/
               time_t          shm_dtime;   /* 最后卸载(解除映射)时间 */
               time_t          shm_ctime;   /* 最后修改时间*/
               pid_t           shm_cpid;    /* 创建者PID */
               pid_t           shm_lpid;    /* 最后一个挂载/卸载PID */
               shmatt_t        shm_nattch;  /* 当前挂载的进程数*/
               ...
           };
struct ipc_perm {
               key_t          __key;    /* Key*/
               uid_t          uid;      /* Effective UID of owner */
               gid_t          gid;      /* Effective GID of owner */
               uid_t          cuid;     /* Effective UID of creator */
               gid_t          cgid;     /* Effective GID of creator */
               unsigned short mode;     /* 权限 */
               unsigned short __seq;    /* Sequence number */
           };

 

 

次のコードは、共有メモリを作成するためのプロセスと独自のプロセス空間にマップし、再びそれを使用し、最後にマップを持ち上げます:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main()
{
    //1.获取key
    key_t key = ftok(".",'x');
    if(key==-1){
        perror("ftok");
        exit(-1);
    }

    //2.创建共享内存
    int shmid = shmget(key,10,IPC_CREAT|0666);
    if(shmid==-1){
        perror("shmget");
        exit(-1);
    }

    //3.映射共享内存
    void *p = shmat(shmid,0,0);
    if(p==(void *)-1){
        perror("shmat");
        exit(-1);
    }

    //4.使用共享内存
    *(int *)p = 100;

    //5.解除映射
    shmdt(p);

    return 0;
}

このプロセスの鍵は、同じ共有メモリIDを取得するために一貫して取得し、このIDを使用してそれらをマッピングして、それを使用し、最終的に共有メモリを削除するためにそれと一緒に以下のコードを通信します。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main()
{
    //1.获取key
    key_t key = ftok(".",'x');
    if(key==-1){
        perror("ftok");
        exit(-1);
    }

    //2.获取共享内存
    int shmid = shmget(key,0,0);
    if(shmid==-1){
        perror("shmget");
        exit(-1);
    }

    //3.映射共享内存
    void *p = shmat(shmid,0,0);
    if(p==(void *)-1){
        perror("shmat");
        exit(-1);
    }

    //4.使用共享内存
    printf("data = %d\n",*(int *)p);

    //5.解除映射
    shmdt(p);

    //6.不再使用删除共享内存
    shmctl(shmid,IPC_RMID,0);

    return 0;
}

しかし、これは標準ではありません!

如果对于同一个资源, 一个进程对它写, 同时另一个进程又对它读

这会乱 !!!

因此产生了进程的互斥和同步(我博客中的信号量集有讲)

 

发布了52 篇原创文章 · 获赞 40 · 访问量 3万+

おすすめ

転載: blog.csdn.net/weixin_40519315/article/details/104210920