Linux IPC总结(全)

qcom ucsi probe qcom ucsi 阅读详情

IPC进程间通信(Inter-Process Communication)就是指多个进程之间相互通信,交换信息的方法。Linux IPC基本上都是从Unix平台上继承而来的。主要包括最初的Unix IPC,System V IPC以及基于Socket的IPC。另外,Linux也支持POSIX IPC。

System V,BSD,POSIX

    System V是Unix操作系统最早的商业发行版之一。它最初由AT&T(American Telephone & Telegraph)开发,最早在1983年发布。System V主要发行了4个版本,其中SVR4(System V Release 4)是最成功的版本。BSD(Berkeley Software Distribution,有时也被称为Berkeley Unix)是加州大学于1977至1995年间开发的。在19世纪八十年代至九十年代之间,System V和BSD代表了Unix的两种主要的操作风格。它们的主要区别如下:

    系统                      System V           BSD
    root脚本位置            /etc/init.d/       /etc/rc.d/
    默认shell                 Bshell             Cshell
    文件系统数据            /etc/mnttab     /etc/mtab
    内核位置                  /UNIX             /vmUnix
    打印机设备                lp                  rlp
    字符串函数                memcopy       bcopy
    终端初始化设置文件    /etc/initab       /etc/ttys
    终端控制                  termio            termios

    Linux系统的操作风格往往介于这两种风格之间。

    POSIX(Portable Operating System Interface [for Unix])是由IEEE(Institute of Electrical and Electronics Engineers,电子电气工程协会)开发的。现有的大部分Unix都遵循POSIX标准,而Linux从一开始就遵循POSIX标准。

最初的Unix IPC

1、信号

    信号是Unix/Linux系统在一定条件下生成的事件。信号是一种异步通信机制,进程不需要执行任何操作来等待信号的到达。信号异步通知接收信号的进程发生了某个事件,然后操作系统将会中断接收到信号的进程的执行,转而去执行相应的信号处理程序。

    (1)注册信号处理函数
        #include <signal.h>
        /*typedef void (*sighandler_t)(int);  sighandler_t signal(int signum,sighandler_t handler);*/
        * void (*signal(int signum, void (*handler)(int)))(int);  //SIG_IGN && SIG_DFL
        * int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);

    (2)发送信号
        #include <signal.h>
        * int kill(pid_t pid,int sig); //#include <sys/types.h> 
        * int raise(int sig);            //kill(getpid(),sig);
        * unsigned int alarm(unsigned int seconds); //(#include <unistd.h>) seconds秒后,向进程本身发送SIGALRM信号。

    (3)信号集
        信号集被定义为:typedef struct {unsigned long sig[_NSIG_WORDS];} sigset_t;
        * int sigaddset(sigset_t *set,int sig);
        * int sigemptyset(sigset_t *set);

2、管道(Pipe)

    管道用来连接不同进程之间的数据流。

    (1)在两个程序之间传递数据的最简单的方法是使用popen()和pclose()函数:
        #include <stdio.h>
        FILE *popen(const char *command, const char *open_mode);
        int pclose(FILE *stream);
    popen()函数首先调用一个shell,然后把command作为参数传递给shell。这样每次调用popen()函数都需要启动两个进程;但是由于在Linux中,所有的参数扩展(parameter expansion)都是由shell执行的,这样command中包含的所有参数扩展都可以在command程序启动之前完成。

    (2)pipe()函数:
        #include <unistd.h>
        int pipe(int pipefd[2]);
    popen()函数只能返回一个管道描述符,并且返回的是文件流(file stream),可以使用函数fread()和fwrite()来访问。pipe()函数可以返回两个管道描述符:pipefd[0]和pipefd[1],任何写入pipefd[1]的数据都可以从pipefd[0]读回;pipe()函数返回的是文件描述符(file descriptor),因此只能使用底层的read()和write()系统调用来访问。pipe()函数通常用来实现父子进程之间的通信。

    (3)命名管道:FIFO
        #include <sys/types.h>
        #include <sys/stat.h>
        int mkfifo(const char *fifo_name, mode_t mode);
    前面两种管道只能用在相关的程序之间,使用命名管道可以解决这个问题。在使用open()打开FIFO时,mode中不能包含O_RDWR。mode最常用的是O_RDONLY,O_WRONLY与O_NONBLOCK的组合。O_NONBLOCK影响了read()和write()在FIFO上的执行方式。

    PS:要想查看库函数用法,最可靠的资料来自Linux manual page:

    $sudo apt-get install manpages-dev

    $man 3 function_name

 

System V IPC

    System V IPC指的是AT&T在System V.2发行版中引入的三种进程间通信工具:(1)信号量,用来管理对共享资源的访问 (2)共享内存,用来高效地实现进程间的数据共享 (3)消息队列,用来实现进程间数据的传递。我们把这三种工具统称为System V IPC的对象,每个对象都具有一个唯一的IPC标识符(identifier)。要保证不同的进程能够获取同一个IPC对象,必须提供一个IPC关键字(IPC key),内核负责把IPC关键字转换成IPC标识符。   

    System V IPC具有相似的语法,一般操作如下:

    (1)选择IPC关键字,可以使用如下三种方式:

       a)IPC_PRIVATE。由内核负责选择一个关键字然后生成一个IPC对象并把IPC标识符直接传递给另一个进程。
       b)直接选择一个关键字。
       c)使用ftok()函数生成一个关键字。

    (2)使用semget()/shmget()/msgget()函数根据IPC关键字key和一个标志flag创建或访问IPC对象。如果key是IPC_PRIVATE;或者key尚未与已经存在的IPC对象相关联且flag中包含IPC_CREAT标志,那么就会创建一个全新的IPC对象。

    (3)使用semctl()/shmctl()/msgctl()函数修改IPC对象的属性。

    (4)使用semctl()/shmctl()/msgctl()函数和IPC_RMID标志销毁IPC实例。

    System V IPC为每个IPC对象设置了一个ipc_perm结构体并在创建IPC对象的时候进行初始化。这个结构体中定义了IPC对象的访问权限和所有者:

    struct ipc_perm{
       uid_t uid;   //所有者的用户id
       gid_t gid;   //所有者的组id
       uid_t cuid;  //创建者的用户id
       gid_t cgid;  //创建者的组id
       mode_t mode; //访问模式
       …
    };

    shell中管理IPC对象的命令是ipcs、ipcmk和ipcrm。

1、信号量(Semaphores)

    System V的信号量集表示的是一个或多个信号量的集合。内核为每个信号量集维护一个semid_ds数据结构,而信号量集中的每个信号量使用一个无名结构体表示,这个结构体至少包含以下成员:
    struct{
        unsigned short semval;//信号量值,总是>=0
        pid_t sempid;  //上一次操作的pid
       …
    };

    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/sem.h>
    (1)创建或访问信号量
        * int semget(key_t key,int nsems,int flag); 
    nsems指定信号量集中信号量的个数,如果只是获取信号量集的标识符(而非新建),那么nsems可以为0。flag的低9位作为信号量的访问权限位,类似于文件的访问权限;如果flag中同时指定了IPC_CREAT和IPC_EXCL,那么如果key已与现存IPC对象想关联的话,函数将会返回EEXIST错误。例如,flag可以为IPC_CREAT|0666。

    (2)控制信号量集
        * int semctl(int semid,int semnum,int cmd,union semun arg);
    对semid信号量集合执行cmd操作;cmd常用的两个值是:SETVAL初始化第semnum个信号量的值为arg.val;IPC_RMID删除信号量。

    (3)对一个或多个信号量进行操作
        * int semop(int semid,struct sembuf *sops,unsigned nsops);
        * struct sembuf{
              unsigned short sem_num;  //信号量索引
              short   sem_op;     //对信号量进行的操作,常用的两个值为-1和+1,分别代表P、V操作
              short   sem_flag;   //比较重要的值是SEM_UNDO:当进程结束时,相应的操作将被取消;同时,如果进程结束时没有释放资源的话,系统会自动释放
           };

2、共享内存

    共享内存允许两个或多个进程共享一定的存储区,因为不需要拷贝数据,所以这是最快的一种IPC。

    #include <sys/ipc.h>
    #include <sys/shm.h>
    (1)创建或访问共享内存
        * int shmget(key_t key,size_t size,int shmflg);

    (2)附加共享内存到进程的地址空间
        * void *shmat(int shmid,const void *shmaddr,int shmflg);//shmaddr通常为NULL,由系统选择共享内存附加的地址;shmflg可以为SHM_RDONLY

    (3)从进程的地址空间分离共享内存
        * int shmdt(const void *shmaddr); //shmaddr是shmat()函数的返回值

    (4)控制共享内存
        * int shmctl(int shmid,int cmd,struct shmid_ds *buf);
        * struct shmid_ds{
              struct ipc_perm shm_perm;
              …
          }; 
    cmd的常用取值有:(a)IPC_STAT获取当前共享内存的shmid_ds结构并保存在buf中(2)IPC_SET使用buf中的值设置当前共享内存的shmid_ds结构(3)IPC_RMID删除当前共享内存

3、消息队列

    消息队列保存在内核中,是一个由消息组成的链表。

    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    (1)创建或访问消息队列
    * int msgget(key_t key,int msgflg);

    (2)操作消息队列
        * int msgsnd(int msqid,const void *msg,size_t nbytes,int msgflg);
    msg指向的结构体必须以一个long int成员开头,作为msgrcv()的消息类型,必须大于0。nbytes指的是msg指向结构体的大小,但不包括long int部分的大小
        * ssize_t msgrcv(int msqid,void *msg,size_t nbytes,long msgtype,int msgflg);
    如果msgtype是0,就返回消息队列中的第一个消息;如果是正整数,就返回队列中的第一个该类型的消息;如果是负数,就返回队列中具有最小值的第一个消息,并且该最小值要小于等于msgtype的绝对值。

    (3)控制消息队列
        * int msgctl(int msqid,int cmd,struct msqid_ds *buf);
        * struct msqid_ds{
              struct ipc_perm msg_perm;
              …
           };

Socket
  套接字(Socket)是由Berkeley在BSD系统中引入的一种基于连接的IPC,是对网络接口(硬件)和网络协议(软件)的抽象。它既解决了无名管道只能在相关进程间单向通信的问题,又解决了网络上不同主机之间无法通信的问题。

  套接字有三个属性:域(domain)、类型(type)和协议(protocol),对应于不同的域,套接字还有一个地址(address)来作为它的名字。

  域(domain)指定了套接字通信所用到的协议族,最常用的域是AF_INET,代表网络套接字,底层协议是IP协议。对于网络套接字,由于服务器端有可能会提供多种服务,客户端需要使用IP端口号来指定特定的服务。AF_UNIX代表本地套接字,使用Unix/Linux文件系统实现。

  IP协议提供了两种通信手段:流(streams)和数据报(datagrams),对应的套接字类型(type)分别为流式套接字和数据报套接字。流式套接字(SOCK_STREAM)用于提供面向连接、可靠的数据传输服务。该服务保证数据能够实现无差错、无重复发送,并按顺序接收。流式套接字使用TCP协议。数据报套接字(SOCK_DGRAM)提供了一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDP协议。

  一种类型的套接字可能可以使用多于一种的协议来实现,套接字的协议(protocol)属性用于指定一种特定的协议。

 

总结:

 

 

 

System V IPC API

 

1,消息队列

int ftok(const char *pathname, int prj_id);

int msgget(key_t key,int msgflag);

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

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

 

2,信号量

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

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

int semop(int semid,struct sembuf *sops,unsigned nsops,struct timespec *timeout);

 

3,共享内存

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

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

  

POSIX IPC API

Android——IPC机制(一)IPC概念以及Binder机制 由于IPC机制牵扯的东西比较多,所以这里将分为一个系列进行总结 主要介绍内如如下: IPC简介 Android中的多进程模式 开启多进程模式 多进程模式的运行机制 IPC基础概念介绍 Serializable接口 Parcelable接口 Binder Android中的IPC方式 使用Bundle 使用文件共享 使用Messenger 使用AIDL 使用ContentProvider 使用 阅读详情

相关推荐

Linux: 命令 lsipc、ipcrm, ipcs

文章目录lsipcipcrm例子 属于util-linux 工具包里的命令。 lsipc 展示ipc相关资源情况。 -m, --shmems shared memory segments -q, --queues message queues -s, --semaphores semaphores -g, --global info about system-wide usage (may be used with -m, -q and -s) -i, --id p

mzhan017的博客 1732

Linux进程间通信(Linux IPC)

在Linux下由很多种进程间通信的方式,在下面主要介绍七种,分别是:匿名管道(PIPE)、命名管道(FIFO)、信号、共享内存映射、共享内存、消息队列、信号量、UNIX域套接字。

Peerless__的博客 7668

从零开始用STM32驱动RGB屏:配置PCLK、DE同步信号的避坑指南

本文详细介绍了如何使用STM32驱动RGB接口LCD屏幕,重点解析了PCLK配置、同步信号极性和DE使能等关键参数的设置方法。通过实战代码示例和常见问题排查指南,帮助开发者避免常见配置错误,实现稳定的显示效果。特别针对800x480 IPS屏提供了优化建议和调试技巧。

sky77的博客 540

LINUX---进程间通信(IPC)

通信

weixin_48651223的博客 3493

NCCL 源码深度解析:从初始化到通信链路构建全流程

本文深入解析了NVIDIA Collective Communication Library (NCCL) 的核心工作机制,从通信组初始化、硬件拓扑发现,到P2P、共享内存及网络传输链路的构建。详细剖析了源码中集合通信任务的执行流程与Proxy线程的协同机制,为开发者进行高性能分布式训练的性能调优与深度问题排查提供了清晰的底层视角。

hp777的博客 551

C#上位机实战:借助NetToPLCSim与西门子S7-1200仿真通信全攻略

本文详细介绍了如何使用C#开发上位机程序,通过NetToPLCSim与西门子S7-1200进行仿真通信的全过程。从环境准备、PLC仿真环境搭建、网络配置到C#代码实现,提供了完整的实战指南和常见问题解决方案,帮助开发者快速掌握工业自动化通信技术。

weixin_30596343的博客 440

FPGA驱动EMMC存储方案:从选型到Verilog实现全流程详解

在FPGA数据采集与存储系统中,非易失大容量存储方案的选择直接影响开发效率与可靠性。EMMC作为内置主控的NAND Flash,通过标准MMC命令集对外提供接口,能大幅简化坏块管理、ECC校验等底层逻辑,有效降低工程复杂度。掌握从初始化命令序列到CMD17/24读写操作的协议细节,是搭建稳定存储链路的基础。基于Verilog的分层控制器架构,可实现命令封装、CRC校验、数据通路复用,配合合理的电源与PCB设计,能够构建高可靠、易扩展的存储接口。在图像采集、长时间数据记录等应用场景中,EMMC以焊接式封装与G

weixin_34275734的博客 383

自动化革命:AI在需求分析、代码生成与测试中的深度应用

在2025年的科技浪潮中,人工智能(AI)已不再是实验室中的概念,而是深度渗透至软件开发的全生命周期。从需求分析的精准捕捉,到代码生成的自动化创作,再到测试环节的智能覆盖,AI正以革命性姿态重塑软件工程的核心环节。本文将结合2025年最新数据与行业实践,解析AI如何在这三大领域实现深度应用。

1510

Linux 下IPC总结(全)

IPC进程间通信(Inter-Process Communication)就是指多个进程之间相互通信,交换信息的方法。Linux IPC基本上都是从Unix平台上继承而来的。主要包括最初的Unix IPC,System V IPC以及基于Socket的IPC。另外,Linux也支持POSIX IPC。 System V,BSD,POSIX     System V是Unix操作系统最早

Live_Today的专栏 685

Blender.粒子效果

Blender.粒子效果 ✦ shift+A新建一个棱角球,细分(之后要分解成许多小颗粒) ✦ 给球添加粒子系统,这时播放粒子会向下掉,力场权重☛重力☛0后,粒子会在球体周围运动 ✦ shift+A添加一个力场,调整力场强度 ✦如果粒子运动太快,我们可以在输出属性中调整时间重映射的原始值 ✦想让粒子在球周围运动而不是发散出去,在物理属性找到力场设置,调整流的大小 ✦S键将球形缩小到看不见 ✦给粒子变添加立方体的形状,在粒子属性里找到渲染选项,将“光晕”改为“物体”,在实例物体中选择新建的立方

weixin_46385629的博客 6669

Anchor graph 对齐文献解读

Align then Fusion: Generalized Large-scale Multi-view Clustering with Anchor Matching Correspondences文献解读

atease0001的博客 1164

Linux IPC 总结(全)

原文: http://www.cnblogs.com/wangkangluo1/archive/2012/05/14/2498786.html IPC进程间通信(Inter-Process Communication)就是指多个进程之间相互通信,交换信息的方法。Linux IPC基本上都是从Unix平台上继承而来的。主要包括最初的Unix IPC,System V IPC以及基于So

Huntinux 754

(王道408考研操作系统)第三章内存管理-第一节1:内存基础知识、程序编译运行原理

注意:本节内容和《计算机组成原理》“存储器”那一部分内容相关性很强,组成原理是从硬件角度,操作系统是从软件角度。因此如果没有学习过这部分的同学,强烈建议先看这一部分 王道计算机组成原理笔记 本文主要会涉及以下必要的内存知识 文章目录一:内存及其作用 一:内存及其作用 内存:内存又称之为主存。是一种硬件设备,作为CPU和硬盘的缓冲区,用于解决其速度不匹配的问题,提高整机性能。程序执行前需要放入内存才能运行 ...

快乐江湖的博客 2792

linux ipc总结(全)

Linux IPC总结(全) 分类:Linux/Unix ABC 2011-08-02 11:25 634人阅读 评论(5) 收藏 举报 IPC进程间通信(Inter-Process Communication)就是指多个进程...

chitu3082的博客 127

学Simulink——基于大数据处理与云计算的场景实例:无人机与云计算中心之间的高效数据传输链路设计

本文以无人机与云计算中心的高效数据传输链路设计为例,手把手指导使用Simulink进行系统级建模。针对智慧城市、灾害监测等场景中无人机采集的海量数据(视频、图像、点云等),构建包含数据源、传输协议、无线链路、云接入和性能分析的五层架构模型。通过智能数据压缩、多链路聚合和QoS优先级调度等关键技术,实现5G+Wi-Fi等多通信技术的自适应切换。仿真结果表明,5G+Wi-Fi链路聚合在城市环境中表现最优,而4G+卫星组合适合偏远地区。该模型为无人机实时数据传输提供了有效的设计方法和优化方向,可拓展至边缘计算、A

xiaoheshang_123的博客 120

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

System V IPC:Linux进程通信的经典机制全解析

System V作为Unix操作系统早期具有重要影响力的商业发行版,由通信巨头AT&T倾心打造,其引入的IPC机制宛如一颗璀璨明珠,在Linux世界中持续闪耀。System V IPC主要涵盖三大核心组件:信号量、共享内存和消息队列,它们携手为进程间的交互提供全方位支持,是保障系统高效运转的幕后英雄。

xx 888

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

上一篇: linux 消息队列
下一篇: __attribute__机制介绍
depaJun
博客等级 码龄16年 20粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值