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
目录
相关文章
|
11月前
|
并行计算 Linux
Linux内核中的线程和进程实现详解
了解进程和线程如何工作,可以帮助我们更好地编写程序,充分利用多核CPU,实现并行计算,提高系统的响应速度和计算效能。记住,适当平衡进程和线程的使用,既要拥有独立空间的'兄弟',也需要在'家庭'中分享和并行的成员。对于这个世界,现在,你应该有一个全新的认识。
373 67
|
10月前
|
Web App开发 Linux 程序员
获取和理解Linux进程以及其PID的基础知识。
总的来说,理解Linux进程及其PID需要我们明白,进程就如同汽车,负责执行任务,而PID则是独特的车牌号,为我们提供了管理的便利。知道这个,我们就可以更好地理解和操作Linux系统,甚至通过对进程的有效管理,让系统运行得更加顺畅。
284 16
|
10月前
|
Unix Linux
对于Linux的进程概念以及进程状态的理解和解析
现在,我们已经了解了Linux进程的基础知识和进程状态的理解了。这就像我们理解了城市中行人的行走和行为模式!希望这个形象的例子能帮助我们更好地理解这个重要的概念,并在实际应用中发挥作用。
201 20
|
9月前
|
监控 Shell Linux
Linux进程控制(详细讲解)
进程等待是系统通过调用特定的接口(如waitwaitpid)来实现的。来进行对子进程状态检测与回收的功能。
213 0
|
9月前
|
存储 负载均衡 算法
Linux2.6内核进程调度队列
本篇文章是Linux进程系列中的最后一篇文章,本来是想放在上一篇文章的结尾的,但是想了想还是单独写一篇文章吧,虽然说这部分内容是比较难的,所有一般来说是简单的提及带过的,但是为了让大家对进程有更深的理解与认识,还是看了一些别人的文章,然后学习了学习,然后对此做了总结,尽可能详细的介绍明白。最后推荐一篇文章Linux的进程优先级 NI 和 PR - 简书。
285 0
|
9月前
|
存储 Linux Shell
Linux进程概念-详细版(二)
在Linux进程概念-详细版(一)中我们解释了什么是进程,以及进程的各种状态,已经对进程有了一定的认识,那么这篇文章将会继续补全上篇文章剩余没有说到的,进程优先级,环境变量,程序地址空间,进程地址空间,以及调度队列。
168 0
|
9月前
|
Linux 调度 C语言
Linux进程概念-详细版(一)
子进程与父进程代码共享,其子进程直接用父进程的代码,其自己本身无代码,所以子进程无法改动代码,平时所说的修改是修改的数据。为什么要创建子进程:为了让其父子进程执行不同的代码块。子进程的数据相对于父进程是会进行写时拷贝(COW)。
230 0
|
12月前
|
存储 Linux 调度
【Linux】进程概念和进程状态
本文详细介绍了Linux系统中进程的核心概念与管理机制。从进程的定义出发,阐述了其作为操作系统资源管理的基本单位的重要性,并深入解析了task_struct结构体的内容及其在进程管理中的作用。同时,文章讲解了进程的基本操作(如获取PID、查看进程信息等)、父进程与子进程的关系(重点分析fork函数)、以及进程的三种主要状态(运行、阻塞、挂起)。此外,还探讨了Linux特有的进程状态表示和孤儿进程的处理方式。通过学习这些内容,读者可以更好地理解Linux进程的运行原理并优化系统性能。
449 4
|
12月前
|
Linux 数据库 Perl
【YashanDB 知识库】如何避免 yasdb 进程被 Linux OOM Killer 杀掉
本文来自YashanDB官网,探讨Linux系统中OOM Killer对数据库服务器的影响及解决方法。当内存接近耗尽时,OOM Killer会杀死占用最多内存的进程,这可能导致数据库主进程被误杀。为避免此问题,可采取两种方法:一是在OS层面关闭OOM Killer,通过修改`/etc/sysctl.conf`文件并重启生效;二是豁免数据库进程,由数据库实例用户借助`sudo`权限调整`oom_score_adj`值。这些措施有助于保护数据库进程免受系统内存管理机制的影响。
|
Linux Shell
Linux 进程前台后台切换与作业控制
进程前台/后台切换及作业控制简介: 在 Shell 中,启动的程序默认为前台进程,会占用终端直到执行完毕。例如,执行 `./shella.sh` 时,终端会被占用。为避免不便,可将命令放到后台运行,如 `./shella.sh &`,此时终端命令行立即返回,可继续输入其他命令。 常用作业控制命令: - `fg %1`:将后台作业切换到前台。 - `Ctrl + Z`:暂停前台作业并放到后台。 - `bg %1`:让暂停的后台作业继续执行。 - `kill %1`:终止后台作业。 优先级调整:
1145 5