• Linux环境编程


    共享内存

            基础特点:

                两个或多个进程之间共享一块由内核统一管理的内存,该内存可以与多个进程的虚拟内存进行映射

                    优点:不需要复制任何信息,直接读写内存,是最快的一种IPC机制

                    缺点:需要考虑同步访问的问题,一般使用信号

                int shmget(key_t key, size_t size, int shmflg);

                功能:创建\获取一块共享内存

                key: IPC键值(独一无二)

                size: 共享内存的大小,获取共享内存时此参数无意义,一般给0

                shmflg:

                    IPC_CREAT   创建共享内存,如已存在直接获取

                    IPC_EXCL    共享内存已存在,返回失败

                    获取时直接给0

                    注意:如果是创建共享内存还需要额外提供共享内存的权限

                        例如: IPC_CREAT|0664

                返回值: IPC标识符,失败-1

                void *shmat(int shmid, const void *shmaddr, int shmflg);

                功能:虚拟内存与共享内存进行映射

                shmid:IPC标识符 shmget的返回值

                shmaddr: 想要映射的虚拟内存首地址,为NULL时系统会自动分配地址

                shmflag:

                    SHM_RDONLY 以只读方式映射共享内存

                    SHM_RND: 只有shmaddr参数不为NULL时才能有效,表示从shmaddr开始向下以整数页方式映射

                返回值:与共享内存映射成功后的虚拟内存首地址,失败返回(void *) -1

                int shmdt(const void *shmaddr);

                功能:取消映射

                shmaddr: 映射成功后的虚拟内存首地址

                int shmctl(int shmid, int cmd, struct shmid_ds *buf);

                功能:删除/控制共享内存

                shmid: IPC标识符

                cmd:

                    IPC_STAT    获取共享内存属性    buf输出型参数

                    IPC_SET     设置共享内存属性    buf输入型参数

                    IPC_RMID    删除共享内存        NULL

                buf

        编程模型:

            进程A                    进程B

            创建共享内存              获取共享内存

            映射共享内存              映射共享内存

            写数据通知其他进程        收到通知并读数据

            取消映射                 取消映射

            删除共享内存

    消息队列:

        基本特点:是由内核负责维护的链式数据队列,不是根据先后顺序出队,而是根据消息类型收发数据

            int msgget(key_t key, int msgflg)

            功能:创建\获取消息队列

            key: IPC键值

            msgflg:

                IPC_CREAT    消息队列已经存在则获取,否则创建

                IPC_EXCL     消息队列已存在则返回错误

                注意:如果创建需要提供权限

            返回值: IPC标识符,失败-1

            int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

            功能:向消息队列发送消息包

            msqid: IPC标识符

            msgp: 要发送的消息包的首地址

                struct msgbuf {

                    long mtype;      //  消息类型

                    char mtext[n];   //  数据  

                };

            msgsz: 数据的字节数,不包含消息类型

            msgflg:

                阻塞发送一般给0

                IPC_NOWAIT  当消息队列满,不等待立即返回

            返回值: 成功返回0,失败-1

            size_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

            功能:从消息队列中接受对应消息包的数据

            msqid: IPC标识符

            msgp: 存储消息包的内存首地址

            msgsz: 存储数据的内存字节数(尽量大些)

            msgtyp: 消息类型(按照类型获取,不按照顺序)

                >0  读取消息类型等于msgtype的消息

                =0  读取消息队列中的第一条消息

                <0  读取消息类型小于abs(msgtyp)的消息,如果有多个则读值最小的

            msgflg

                IPC_NOWAIT  消息队列都不符合时不阻塞,立即返回

                MSG_EXCEPT  如果msgtyp>0,则读取第一条不等于msgtyp的消息

                MSG_NOERROR 如果不包含此标志,如果实际发送过来的数据字节>接受的字节数,则返回失败

                    如果包含此标志,那么就只读取接收的字节数,一定会成功

            返回值:成功读取到数据的字节数

            int msgctl(int msqid,int cmd, struct msqid_ds *buf);

            msg_qid: IPC标识符

                IPC_STAT    获取消息队列属性    buf输出型参数

                IPC_SET     设置消息队列属性    buf输入型参数

                IPC_RMID    删除消息队列        NULL

            buf

            编程模型:

                进程A                       进程B

              创建消息队列                 获取消息队列

              发送消息                     获取消息

              获取消息                     发送消息

              删除消息队列          

    信号量:

        基本特点:由内核管理的一个"全局变量",用于记录共享资源的数量,限制进程对共享资源的访问使用

        信号量是一种数据操作锁,本身是不具备数据交互功能,而是通过控制其他的通信资源从而匹配实现进程间通信

        1、如果信号量的值大于0,说明可以使用资源,使用时需要信号量-1,然后再使用

        2、如果信号量的值等于0,说明没有资源可使用,此时进程进入休眠,直到信号量大于>0,进程会被唤醒,执行步骤1

        3、当资源使用完毕,把信号量+1,正在休眠的进程就会被唤醒

       

        int semget(key_t key, int nsems, int semflg);

        功能: 创建\获取信号量

        key: IPC键值

        nsems: 信号量的数量 一般写1

        semflg:

            IPC_CREAT  信号量已存在则获取,否则创建

            IPC_EXCL    信号量已存在则返回错误

            注意:如果创建需要提供权限

        返回值: IPC标识符 失败-1

        int semctl(int semid, int semnum, int cmd, ...);

        功能:删除、控制信号量

        semid: IPC标识符

        semnum: 要操作的第几个信号量,从0开始,下标

        cmd:

            IPC_STAT    获取信号量属性     buf输出型参数

            IPC_SET     设置信号量属性     buf输入型参数

            IPC_RMID    删除信号量         NULL

            SETVAL      设置某个信号量的值  

            SETALL      设置所有信号量的值  

            GETVAL      获取某个信号量的值

            GETALL      获取所有信号量的值

            GETNCNT     获取等待拿资源的进程的数量

        int semop(int semid, struct sembuf *sops, size_t nsops);

        功能:对信号量进行加减操作

        semid: IPC标识符

        sembuf {

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

            short          sem_op;

                    1  信号量+1

                    -1 信号量-1 如果不能减,则默认阻塞

            short          sem_flg;

                    IPC_NOWAIT  不阻塞

                    SEM_UNDO    如果进程终止没有手动还资源,系统会自动帮你还

        }

        nsops: 表示sops指向多少个结构体数量 一般写1


     

  • 相关阅读:
    3357: 「JLOI2015」管道连接
    城市引力分析
    原生安卓打包Vue 项目成apk安装包
    开放原子开源基金会秘书长孙文龙:要打造以开发者为本的开源服务平台
    中秋国庆,双节同乐
    vue前后端端口不一致解决方案
    【校招VIP】前端计算机网络之webSocket相关
    [NISACTF 2022]hardsql - quine注入
    asio中的定时器steady_timer和deadline_timer
    代码随想录算法训练营day35 | 0-1背包理论基础、416. 分割等和子集
  • 原文地址:https://blog.csdn.net/weixin_61180910/article/details/126717465