Linux系统编程(三)

IPC(进程间通信)
文件类型:
- 文件
d 目录
l 符号链接
伪文件:
s 套接字
b 块设备
c 字符设备
D 管道

管道:
是一种最基本的IPC机制,作用于有血缘关系的进程之间,完成数据传递。调用pipe系统函数即可创建一个管道,有如下特质
①本质是一个伪文件(实为内核缓冲区)
②由两个文件描述符引用,一个表示读端一个表示写端
③规定数据从管道的写端流入管道,从读端流出
管道的原理:管道实为内核使用的环形队列机制,借助内核缓冲区(4k)实现
管道的局限性:
①数据自己读不能自己写
②数据一旦被读走,便不再管道中存在,不可反复读取
③由于管道采用半双工通信方式。因此,数据只能在一个方向上流动
④只有在有公共进程间使用管道
pipe
创建管道
int pipe(int pipefd[2])
成功 0 失败 -1 设置errno
函数调用成功返回r/w两个文件描述符。无需open但需要手动close.规定fd[0]为读 fd[1]为写
创建管道成功以后,创建该管道的进程(父进程)同时掌握管道的读端和写端。如何书写父子进程间通信呢。通常由下面的方法
管道一般读写行为

这里写图片描述

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
int fd[2];
pid_t pid;
int ret = pipe(fd);
if(ret == -1){
    perror("pipe error");
    exit(1);
}
    pid = fork();
    if(pid == -1){
    perror("pipe error");
    exit(1);
    }else if(pid == 0){//子  读数据
    close(fd[1]);
    char buf[1024];
    ret = read(fd[0],buf,sizeof(buf));
    if(ret == 0){
    printf("------\n");
        }
        write(STDOUT_FILENO,buf,ret);
    }else{
    close(fd[0]);
    write(fd[1],"hello pipe\n",strlen("hello pipe\n"));
    }
return 0;
}

fifo(有名管道)
用于非血缘关系进程间通信
共享内存:
1mmap函数:参数
返回值
void *mmap(void *addr,size_length,int port,int flags,int fd, off_toffset)
返回:成功:返回创建的映射区首地址;失败:MAP_FAILED宏参数:
addr:建立映射区的首地址,由linux内核指定。使用时直接传递NULL
length:欲创建映射区的大小
prot:映射区权限 PROT_READ,PROT_WRITE,PROT_READ|PROT_WRITE
flags:标志位参数(常用于设定更新物理区域,设置共享,创建匿名区)MAP_SHARED:会将映射区所做的操作反映到物理设备(磁盘)上
MAP_PRIVATE:映射区所做的修改不会反映到物理设备
fd :用来建立映射区的文件描述符
offset:映射文件的偏移(4k的整数倍)

#include<fcntl.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/mman.h>
#include<string.h>
int main(void)
{
    int len ret;
    char *p = NULL;
    int fd = open("mytest.txt",O_CREAT|O_EDWR,0644);
    if(fd < 0){
    perror("open error");
    exit(1);
}
    len = ftruncate(fd, 4);
    if(len == -1){
    perror("ftruncate error");
    exit(1);
}
    p = mmap(NULL,4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    if(p == MAP_FAILED){
    perror("mmap error");
    exit(1);
}
    strcpy(p,"abc")//写数据
    ret = munmap(p,4);
    if(ret == -1){
    perror("munmap error");
    exit(1);
    }
    close(fd);
    return 0;
}

注意:①创建映射区的权限要小于等于打开文件
②创建文件映射区的时候隐含一次对文件的读操作
③ offset必须是4k的整数倍(MMU帮助映射的,所以要为4k)
④ 一定检测mmap的返回值
⑤文件描述符先关闭对创建映射区没有影响
这里写图片描述
mmap 父子进程间通信
父子等有血缘关系的进程之间也可以通过mmap建立映射区来完成数据通信,但相应的在创建映射区时指定对应的标志位参数flags:
MAP_PRIVATE:(私有映射)父子进程各自独占映射区
MAP_SHARED(共享映射)父子进程共享映射
结论:父子进程共享 1 打开的文件 2mmap建立的映射区(必须使用MAP_SHARED)
4匿名映射区
同样需要借助标志位参数flags来指定。
使用MAP_ANONYMOUS
如:
int *p = mmap(NULL,4,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
“4”随意列举,该位置表示大小,可依据实际需要填写。
注意:MAP_ANONYMOUS 和MAP_ANON这两个宏是linux操作系统特有的宏,在类linux系统中无该宏,可以使用如下两步完成匿名映射区的建立。
①fd = open(“/dev/zero”,O_RDWR);
② p = mmap(NULL,size,PROT_READ|PROT_WRITE,MMAP_SHARED,fd,0)

mmap用于非血缘关系进程间通信

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值