Linux进程间的通信万字总结大全

简介: POSIX(Portable Operating System Interface for Computing Systems)是由IEEE 和ISO/IEC 开发的一簇标准。该标准是基于现有的UNIX 实践和经验,描述了操作系统的调用服务接口,用于保证编制的应用程序可以在源代码一级上在多种操作系统上移植运行。它是在1980 年早期一个UNIX 用户组(usr/group)的早期工作的基础上取得的。该UNIX 用户组原来试图将AT&T 的系统V 和Berkeley CSRG的BSD 系统的调用接口之间的区别

posix:

POSIX(Portable Operating System Interface for Computing Systems)是由IEEE 和ISO/IEC 开发的一簇标准。该标准是基于现有的UNIX 实践和经验,描述了操作系统的调用服务接口,用于保证编制的应用程序可以在源代码一级上在多种操作系统上移植运行。它是在1980 年早期一个UNIX 用户组(usr/group)的早期工作的基础上取得的。该UNIX 用户组原来试图将AT&T 的系统V 和Berkeley CSRG的BSD 系统的调用接口之间的区别重新调和集成,从而于1984 年产生了/usr/group 标准。1985 年,IEEE操作系统技术委员会标准小组委员会(TCOS-SS)开始在ANSI 的支持下责成IEEE 标准委员会制定有关程序源代码可移植性操作系统服务接口正式标准。到了1986 年4 月,IEEE 就制定出了试用标准。第一个正式标准是在1988 年9 月份批准的(IEEE 1003.1-1988),也既以后经常提到的POSIX.1 标准。

System V:

System V, 曾经也被称为 AT&T System V,是Unix操作系统众多版本中的一支。它最初由 AT&T 开发,在1983年第一次发布。一共发行了4个 System V 的主要版本:版本1、2、3 和 4。System V Release 4,或者称为SVR4,是最成功的版本,成为一些UNIX共同特性的源头,例如 ”SysV 初始化脚本“ (/etc/init.d),用来控制系统启动和关闭,System V Interface Definition (SVID) 是一个System V 如何工作的标准定义。
AT&T 出售运行System V的专有硬件,但许多(或许是大多数)客户在其上运行一个转售的版本,这个版本基于 AT&T 的实现说明。流行的SysV 衍生版本包括 Dell SVR4 和 Bull SVR4。当今广泛使用的 System V 版本是 SCO OpenServer,基于 System V Release 3,以及SUN Solaris 和 SCO UnixWare,都基于 System V Release 4。
System V 是 AT&T 的第一个商业UNIX版本(UNIX System III)的加强。传统上,System V 被看作是两种UNIX"风味"之一(另一个是 BSD)。然而,随着一些并不基于这两者代码的UNIX实现的出现,例如 Linux 和 QNX, 这一归纳不再准确,但不论如何,像POSIX这样的标准化努力一直在试图减少各种实现之间的不同。
POSIX IPC函数汇总
消息队列 信号量 共享内存区
头文件
创建,打开或删除IPC的函数 mq_open
mq_close
mq_unlink
sem_open
sem_close
sem_unlink
sem_init
sem_destroy
shm_open
shm_unlink
控制IPC操作的函数 mq_getattr
mq_setattr
ftruncate
fstat
IPC操作函数 mq_send
mq_receive
mq_notify
sem_wait
sem_trywait
sem_post
sem_getvalue
mmap
munmap
权限属性
说明 mq_open sem_open shm_open
只读
只写
读写
O_RDONLY
O_WRONLY
O_RDWR
O_RDONLY

O_RDWR
若不存在就创建
排他性创建
O_CREATE
O_EXCL
O_CREATE
O_EXCL
O_CREATE
O_EXCL
非阻塞模式
若以存在则截断
O_NONBLOCK
O_TRUNC

这些常值在中定义

#define FILE_MODE(S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)

常值 说明
S_IRUSE
S_IWUSE
用户读
用户写
S_IRGRP
S_IWGRP
组成员读
组成员写
S_IROTH
S_IWOTH
其他用户读
其他用户写
System V IPC函数总结
消息队列 信号量 共享内存区
头文件
创建,打开或删除IPC的函数 msgget semget shmget
控制IPC操作的函数 msgctl semctl shmctl
IPC操作函数 msgsend
msgrcv
semop shmat
shmdt

管道和fifo

#include <unistd.h>
int pipe(int fd[2]);//成功返回0,失败返回-1
//fd[0]读,fd[1]写
//单向管道,只能一边读另一边写

popen和pclose

#include <stdio.h>
FILE* popen(const char* command, const chat* type);
int      pclose(FILE* stream);
/*
command是一个shell标准命令行
如果type为r,那么调用进程读进command的标准输出
如果type为w,那么调用进程读进command的标准输入
*/

FIFO

#include <sys/types.h>
#incluse <sys/stat.h>
int mkfifo(const char* pathname,mode_t mode);
//pathname:路径名
//mode:权限位,默认(O_CREATE | O_EXCL)
//可以使用open打开,read和write等读写函数
//读写具有原子性

POSIX消息队列

#include <mqueue>
struct mq_attr{
   
    long mq_flags;//阻塞标志, 0或O_NONBLOCK
    long mq_maxmsg;//最大消息数
    long mq_msgsize;//每个消息最大大小
    long mq_curmsgs;//当前消息数
};
mqd_t mq_open(const char* name,int flag, ...);//成功返回描述符,失败返回-1
/*
name:地址
flag:属性
第四个参数可以传递mq_addr指针,api只关注mq_maxmsg和mq_msgsize,
*/
//设置和获取消息队列的属性
int mq_getattr(mqd_t mqdes,struct mq_attr* attr);//只使用mq_flags参数,
int mq_setattr(mqd_t mqdes,const struct mq_attr* attr, struct mq_attr* oattr);
//msg_prio优先级等级,可以值为空
int mq_send(mqd_t mqdes, const char *msg_ptr,size_t msg_len, unsigned int msg_prio);
ssize_t mq_receive(mqd_t mqdes, char *msg_ptr,size_t msg_len, unsigned int *msg_prio);

int mq_notifiy(mqd_t mqdes,const struct sigevent* notification);//信号通知
int mq_unlink(const char *name);//减少一个内核计数

System V消息队列

#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h>
//key:既可以是ftok的返回值,也可以是常值IPC_PRIVATE,msgflg权限属性
int msgget(key_t key, int msgflg);//创建一个新的消息队列或者访问一个已存在的消息队列
struct msgbuf{
   
    long type;
    char mtext[1];
}//msgp默认类型,可自定义
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);//成功返回0,失败返回-1
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);//成功返回写入字节数,失败返回-1
int msgctl(int msqid, int cmd, struct msqid_ds *buf);//控制操作
/*
IPC_RMID 从系统中删除由ms?id指定的消息队列。当前在该队列上的任何消息都被丢弃。我们已在图3-7中看到过这种操作的例子。对于该命令而言,msgctl函数的第三个参数被忽略。
IPC_SET 给所指定的消息队列设置其msqid_ds结构的以下4个成员:msg_perm.uid、msg_perm.gid、msg_perm.mode和msg_qbytes。它们的值来自由buff参数指向的结构中的相应成员。
IPC_STAT (通过buff参数)给调用者返回与所指定消息队列对应的当前msqid_ds结构。
*/

posix信号量

有名信号量(基于文件) 基于内存的信号量
sem_open() sem_init()
\ /
sem_wait()
sem_trywait()
sem_post()
sem_getvalue()
/ \
sem_close() sem_destroy()
sem_unlink()

有名信号量既可以用于线程间同步,也可以用于进程间同步,

有名信号量(基于文件)

#include <semapore.h>
//打开一个有名信号量
sem_t* sem_open(const char* name, int oflag,...
                /*mode_t mode, unsigned int value*/);
/*
name:文件名称
oflag:文件权限属性
mode:用户权限属性
value:信号初始值
返回值:成功返回指向信号量的指针
*/
//关闭信号量
int sem_close(sem_t *sem);
int sem_unlink(const char *name);

基于内存的信号量

int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_destroy(sem_t *sem);
//获取信号量
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);

//投入信号量
int sem_post(sem_t *sem);
//获取信号量的数量
int sem_getvalue(sem_t *sem, int *sval);

//成功返回0,失败返回-1

System V 信号量

共享内存

posix共享内存

//创建共享内存区或打开一个已经存在的共享内存区
int shm_open(const char *name, int oflag, mode_t mode);
int shm_unlink(const char *name);
//oflag:文件权限属性
//mode:用户权限属性
//成0败-1

//ftruncate会将参数fd指定的文件大小改为参数length指定的大小。
int ftruncate(int fd, off_t length);
//获取文件状态
int stat(const char *pathname, struct stat *statbuf);
int fstat(int fd, struct stat *statbuf);

mmap可用于进程间的通信,也可用于文件映射(零拷贝技术)

  1. 内存映射文件(通过open函数获取的fd)
  2. 共享内存区对象(通过shm_open获取的fd)
#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
/*
addr:告诉内核映射的起始地址,一般置为null,表示由内核分配内存
length:映射长度
port:
        PROT_READ:可读
        PROT_WRITE:可写
        PROT_EXEC:可执行
        PROT_NOTE:不可访问
flags:
        MAP_SHARED:变动是共享的(对与参与映射的进程和底层文件对象的修改都是共享的)
        MAP_PRIVATE:变动是私有的(对数据做的修改只对该进程可见,不修改底层对象数据)
        MAP_FIXED:准确的解释addr参数(不建议使用)
fd:文件描述符
offset:起始偏移地址
返回值:返回映射内存的起始地址
*/
int munmap(void *addr, size_t length);//释放共享内存

//如果对mmap进行修改后想要立即同步底层文件对象数据(例如硬盘文件对象数据),可调用msync
int msync(void *addr, size_t length, int flags);
/*flags:
        MS_ASYNC:执行异步读写
        MS_SYNC:执行同步读写
        MS_INVALIDATE:使高速缓冲区的数据失效
返回值:成0败-1
*/
相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
14天前
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
本文旨在探讨Linux操作系统中的进程管理机制,包括进程的创建、执行、调度和终止等环节。通过对Linux内核中相关模块的分析,揭示其高效的进程管理策略,为开发者提供优化程序性能和资源利用率的参考。
39 1
|
3天前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
35 13
|
9天前
|
SQL 运维 监控
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
|
17天前
|
运维 监控 Linux
Linux操作系统的守护进程与服务管理深度剖析####
本文作为一篇技术性文章,旨在深入探讨Linux操作系统中守护进程与服务管理的机制、工具及实践策略。不同于传统的摘要概述,本文将以“守护进程的生命周期”为核心线索,串联起Linux服务管理的各个方面,从守护进程的定义与特性出发,逐步深入到Systemd的工作原理、服务单元文件编写、服务状态管理以及故障排查技巧,为读者呈现一幅Linux服务管理的全景图。 ####
|
23天前
|
缓存 算法 Linux
Linux内核的心脏:深入理解进程调度器
本文探讨了Linux操作系统中至关重要的组成部分——进程调度器。通过分析其工作原理、调度算法以及在不同场景下的表现,揭示它是如何高效管理CPU资源,确保系统响应性和公平性的。本文旨在为读者提供一个清晰的视图,了解在多任务环境下,Linux是如何智能地分配处理器时间给各个进程的。
|
1月前
|
存储 运维 监控
深入Linux基础:文件系统与进程管理详解
深入Linux基础:文件系统与进程管理详解
75 8
|
1月前
|
网络协议 Linux 虚拟化
如何在 Linux 系统中查看进程的详细信息?
如何在 Linux 系统中查看进程的详细信息?
61 1
|
1月前
|
Linux
如何在 Linux 系统中查看进程占用的内存?
如何在 Linux 系统中查看进程占用的内存?
|
1月前
|
存储 Unix Linux
进程间通信方式-----管道通信
【10月更文挑战第29天】管道通信是一种重要的进程间通信机制,它为进程间的数据传输和同步提供了一种简单有效的方法。通过合理地使用管道通信,可以实现不同进程之间的协作,提高系统的整体性能和效率。
|
1月前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
70 4
下一篇
DataWorks