IPC进程间通信(interprocess communicate)
为什么需要ipc ,进程空间都是独立。但是进程和进程之间有数据共享或交换的需求。
种类
1、古老的通信方式
无名管道 有名管道 信号
2、IPC对象通信( system v BSD suse fedora kernel.org)
消息队列(用的相对少,这里不讨论)
共享内存
信号量集
3、socket通信
网络通信
(管道的底层实现是队列)
无名管道(匿名管道) unnamed pipe
使用说明:
无名管道 ===》pipe ==》只能给有亲缘关系进程通信
管道的特性:
1、管道是 半双工的工作模式 , 实际编程使用,会当单工使用。
2、所有的管道都是特殊的文件不支持定位操作。lseek->> fd fseek ->>FILE*
3、管道是特殊文件,读写(首选)使用文件IO ,open,read,write,close; 可选(标准io带缓存区)
fgets,fread,fgetc,
1.读端存在,一直向管道中去写,超过64k,写会阻塞。 写段写的太快
2.写端是存在的,读管道,如果管道为空的话,读会阻塞。 读段读的太快
3.管道破裂,,读端关闭,写管道。 会导致写段退出
4. read 0 ,写端关闭,如果管道没有内容,read 0 ; 进程间通信结束。

编程顺序:创建管道 ==》fork-->读写管道 ==》关闭管道
int pipe(int pipefd[2]);
功能:创建并打开一个无名管道
参数:pipefd[0] ==>无名管道的固定读端
pipefd[1] ==>无名管道的固定写端
返回值:成功 0
失败 -1;
有名管道
使用说明:
有名管道 ===》fifo ==》可以给任意单机进程通信 .有文件名称的管道。文件系统中可见
编程步骤: 创建有名管道 》打开有名管道 ==》读写管道》关闭管道 ==》卸载有名管道
特性:
和匿名管道特性一致。 额外的, 如果有一端没有打开,则默认在open函数部分阻塞。
int mkfifo(const char *pathname, mode_t mode);
功能:在指定的pathname路径+名称下创建一个权限为
mode的有名管道文件。
参数:pathname要创建的有名管道路径+名称
mode 8进制文件权限。
返回值:成功 0
失败 -1;
信号通信
应用:异步通信。 通知机制。 随机事件。
信号发送和接收的过程:
1.根据需要(随机事件)发生信号。
2.linux 接收到信号发生请求,在pcb的链表中,查找对应的pid号(1000),
3.找到对应进程后,使原来工作流程先暂停下,执行pcb 中,信号处理函数 对应下标的函数。(如果发送信号2 .则调用handle2)
4.当handle2 执行完毕后,原来进程的代码,继续运行。


系统中对信号的说明和相关默认处理行为
man 7 signal



信号相关函数
发送信号
int kill(pid_t pid, int sig);
功能:通过该函数可以给pid进程发送信号为sig的系统信号。
参数:pid 要接收信号的进程pid
sig 当前程序要发送的信号编号 《=== kill -l
返回值:成功 0
失败 -1;
信号的捕获,自定义处理
void ( *signal(int signum, void (*handler)(int)) ) (int);
sighandler_t signal(int signum, sighandler_t handler);
handler有二个宏表示:
SIG_DFL 表示默认处理
SIG_IGN 表示忽略处理
fun 表示自定义处理
共享内存
由 system V (unix 操作系统) 提供一种进程间通信的方式。

1.函数调用的步骤
key 》申请对象 ==》映射对象》读写对象 ==》撤销映射 ==》删除对象
2.与管道相关区别
与管道对比
1.对于读写进程而言, 双方都可以读写
2.没有读阻塞
3.没有写阻塞。 共享内存需要和其他ipc (信号,或 信号量集(同步操作))进行搭配使用
4.是一个初级内存区域(像字符数组)
5.不删除数据,数据保持的
6.相对来说,共享内存空间可以自定义(4K *n ), 大空间
相关函数接口
key_t ftok(const char *pathname, int proj_id);
功能:通过该函数可以将pathname指定的路径用来以
proj_id生成唯一的临时键值。
参数:pathname 路径+名称===》任意文件,只要不会
被删除重建即可。
proj_id 整形的数字,一般用ASCII码的单字符
表示与参数1的运算。
返回值:成功 返回唯一键值
失败 -1;
int shmget(key_t key, size_t size, int shmflg);
功能:使用唯一键值key向内核提出共享内存使用申请
参数:key 唯一键值
size 要申请的共享内存大小
shmflg 申请的共享内存访问权限,八进制表示
如果是第一个申请,则用IPC_CREAT
如果要检测是否存在,用IPC_EXCL
返回值:成功 返回共享内存id,一般用shmid表示
失败 -1;
映射对象:shmat()
void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:将指定shmid对应的共享内存映射到本地内存。
参数:shmid 要映射的本地内存
shmaddr 本地可用的地址,如果不确定则用NULL,表示
由系统自动分配。
shmflg
0,表示读写
SHM_RDONLY,只读
返回值:成功 返回映射的地址,一般等于shmaddr
失败 (void*)-1
对内存的读写操作
memcpy(); //二进制对象
strcpy(); //字符串对象
撤销映射:shmdt
int shmdt(const void *shmaddr);
功能:将本地内存与共享内存断开映射关系。
参数:shmaddr 要断开的映射地址。
返回值:成功 0
失败 -1;
删除对象:shmctl
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
功能:修改共享内存属性,也可以删除指定的共享内存对象。
参数:shmid 要删除的共享内存对象
cmd IPC_RMID 删除对象的宏
buff NULL 表示只删除对象。
返回值:成功 0
失败 -1
ipcs -a 查询共享内存,信号量集,消息队列
ipcrm -m 删除共享内存
相关命令
ipcs -a 查询共享内存,信号量集,消息队列
ipcrm -m 删除共享内存
&spm=1001.2101.3001.5002&articleId=156157714&d=1&t=3&u=d6baacfb9bd94cbb9a35c3a07b05d94e)
1260

被折叠的 条评论
为什么被折叠?



