管道-(1)

1.          共享内存

  共享内存 - 内核管理一块物理内存,允许不同的进程访问,媒介就是 物理内存,最快的IPC。

  编程步骤:

   1 先获得key。

     key_t key = ftok();

   2 创建/获取内部ID。

     int shmid = shmget(key,flags);

   3 挂接(映射)共享内存 shmat(),返回首地址

   4 使用共享内存

   5 脱接共享内存(解除映射) shmdt()

   6 如果不再使用,用 shmctl(IPC_RMID)删除

 

  共享内存虽然最快,但有致命的弱点:多进程协调工作基本无法控制(比如:多进程写)。消息队列很好的解决了这个问题。

 

2.          消息队列

  消息队列(重点) - 消息就是存放数据的单位。

   在消息队列中,把需要交互的数据封存成一个消息,把消息放入队列中。每个进程都可以从队列中放入/取出消息。消息队列 比较快,以内存中的队列做媒介(内核管理)。

  消息队列的使用步骤:

    1 生成key。 - 头文件 或 ftok()

    2 创建/获取 消息队列的ID。

     int msgid = msgget(key,flags);

    3 发送和接收消息,函数:

     msgsnd(); - 发送

     msgrcv(); - 接收

    4 如果使用完毕,可以使用

      msgctl(IPC_RMID)删除。

 消息类型 :

   消息分为无类型消息和有类型消息:

    无类型消息:任意类型,比如:整数、字符串、浮点

    有类型消息:必须是结构,而且结构的第一个成员必须是long,格式:

    struct 名称{ //名称可以是任意标识符

      long mtype;//消息类型

      char buf[256];//任意类型 存储数据

    };    

   消息类型必须大于0,因为 0 代表任意类型。

   msgsnd(msgid,&msg,sizeof(数据),flags)

   第二个参数&msg 就是 消息结构的指针

   第三个参数是 数据的size,不包括类型的大小(如果包括也可以,但接受时也要包括)。

   flags可以是0 - 阻塞,IPC_NOWAIT - 非阻塞

 

   msgrcv(msgid,&msg,sizeof(数据),

   long msgtype,flags)

    接收无类型消息时,msgtype给0,代表任意类型。此时消息队列出队的方式就是 先入先出。

    接收有类型消息时,msgtype可以是:

    0 代表任意类型,效果和无类型一样先入先出

    >0 代表对应类型,只有该类型的消息会出队,如果有多个相同类型的依然先入先出,如果没有对应类型的 阻塞/返回错误。

    <0 接收小于等于msgtype的绝对值的消息,并且是从最小值到最大值的次序出队。

    

3.          信号量集:

 

信号量集 - XSI IPC的方式。但和共享内存、消息队列有很大的区别,信号量集 其实就是一个 信号量的数组。信号量(semaphore) 就是一个计数器。用于控制 访问同一资源的 最大并行(同时运行)进程数。当信号量到达0时,再有进程访问就会被阻塞,直到有其它进程释放信号量才能访问。

  信号量的工作方式:先设成最大值,然后有进程访问就 -1 ,结束访问就 +1 ,当计数为0时,就阻塞或者返回错误(非阻塞方式),直到计数再次为正 为止。

  IPC对应的是信号量集,而不是单个的信号量,即使只有一个信号量,也要做成长度为1的信号量集。

  信号量集的编程步骤:

   1 生成 key。

   2 创建/获取 信号量集的 内部ID。

    semget(key,数组长度,flags);

    返回信号量集的ID

   3 如果是新建信号量集,需要 设置每个信号量的初始值。

    semctl(semid,下标,SETVAL,初始值);

    设置某个信号量的初始值。

   4 使用信号量集

   5 如果不用了,可以删除 semctl(RMID)

   如何使用信号量集:

    semop()函数

  int semop(int semid, struct sembuf

    semoparray[],size_t nops);

 

    参数semoparray是一个指针,它指向一个信号量操作数组,信号量操作由sembuf结构表示:

  struct sembuf{

    unsigned short sem_num;//信号量的下标

    short sem_op; //信号量操作方式。-1,0,1

    short sem_flg; //信号量的操作标记,默认为0,也可以用IPC_NOWAIT代表非阻塞

  };

 

posted on 2017-02-23 14:59  aiyq195  阅读(129)  评论(0编辑  收藏  举报

导航