zoukankan      html  css  js  c++  java
  • 管道-(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代表非阻塞

      };

  • 相关阅读:
    maven命令
    一个Maven项目在eclipse中正常,但在IDEA中启动时报错
    idea导入eclipse的普通web项目
    idea启动慢的解决办法
    如何在idea里切换项目不同分支
    定时任务
    springboot项目打成war包
    springboot配置信息
    Controller层方法传参和返回字符串
    [C#学习] popupControlContainer控件
  • 原文地址:https://www.cnblogs.com/aiyq195/p/6433497.html
Copyright © 2011-2022 走看看