管道:
#include /* Obtain O_* constant definitions */
#include
int pipe2(int pipefd[2], int flags);
fd[0]:管道读端
fd[1]:管道写端
返回值:
成功:0
失败-1 errno
#include
#include
#include
#include
#include
#include
#include
void sys_err(const char*str)
{
perror(str);
exit(1);
}
int main(int argc,char*argv[])
{
int fd[2];
int ret = pipe(fd);
if(ret == -1)
{
sys_err("pipe error");
}
pid_t pid = fork();
if(pid==0)
{
// sleep(2);
char buf[4096] = {0};
read(fd[0],buf,4096);
printf("child read: %s\n",buf);
}
else if(pid > 0)
{
sleep(2);
write(fd[1],"hello\n",6);
}
return 0;
}
读管道
管道有数据,read返回实际读到的字节数
无数据 1)无写端,返回0(类似读到文件末尾)
2)有写端,阻塞等待。
写管道
无读端,异常终止(SIGPIPE信号)
有读端,1)管道已满,阻塞等待
2)管道未满,返回实际写出的字节数
父子进程ls | wc -l
#include
#include
#include
#include
#include
#include
#include
void sys_err(const char*str)
{
perror(str);
exit(1);
}
int main(int argc,char*argv)
{
pid_t pid;
int fd[2];
//先创建管道
pipe(fd);
pid = fork();
if(pid==0) //子进程实现wc -l
{
close(fd[1]); //子进程读管道关闭写端
dup2(fd[0],STDIN_FILENO); //让wc从管道的读端,读数据
execlp("wc","wc","-l",NULL);
}
else if(pid > 0)
{
close(fd[0]); //父进程写关闭读端。
// 讲写出到屏幕的ls结果,写入到管道写端
dup2(fd[1],STDOUT_FILENO);
execlp("ls","ls",NULL);
}
return 0;
}
兄弟进程 ls | wc -l
#include
#include
#include
#include
#include
#include
#include
#include
void sys_err(const char* str) {
perror(str);
exit(1);
}
int main(int argc, char* argv[]) {
int i = 0;
pid_t pid;
int fd[2] = {0};
pipe(fd);
for(i = 0; i < 2; i++) {
if ((pid = fork()) == 0) {
break;
}
}
if (i == 0) { // 兄
close(fd[0]);
dup2(fd[1], STDOUT_FILENO);
execlp("ls", "ls", NULL);
} else if (i == 1) { // 弟
close(fd[1]);
dup2(fd[0], STDIN_FILENO);
execlp("wc", "wc", "-l", NULL);
} else { // 父进程
close(fd[0]);
close(fd[1]);
for (i = 0; i < 2; i++)
wait(NULL);
}
return 0;
}
#include
long fpathconf(int fd, int name);
long pathconf(const char *path, int name);
_PC_PIPE_BUF 宏
int mkfifo(const char*pathname,mode_t mode)
可以用于无血缘关系进程间通信。
读端和写端打开fifo管道方式不同。
管道中的数据一次性读走。
#include
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
addr:指定映射首地址,设置为NULL,表示让系统自动分配。
length:共享内存映射区的大小 <= 文件实际的大小
prot:共享内存映射区的读写属性。PORT_READ|PORT_WRITE
flags:标注共享内存映射区的共享属性:
MAP_SHARED,对共享内存所作的修改,会反应到物理磁盘文件上。
MAP_PRIVATE,不会反映到物理磁盘文件上。
fd: 用来创建共享内存映射区的那个文件的文件描述符
offset:默认0,表示映射文件全部!偏移位置必须是4k整数倍。
返回值:
成功:映射区的首地址
失败:MAP_FAILED(void*(-1)) errno
int munmap(void *addr, size_t length);
参1: mmap()函数的返回值
参2:共享内存映射区大小
返回值:
成功:0
失败:-1
1、fd = open("文件名",O_RDWR);
2、mmap(NULL,有效文件大小,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
#include
#include
#include
#include
#include
#include
#include
#include
void sys_err(const char*str)
{
perror(str);
exit(1);
}
int main(int argc,char*argv[])
{
int fd = open("test.mmap",O_RDWR|O_CREAT|O_TRUNC,0664);
ftruncate(fd,4);
char* memp;
memp = mmap(NULL,4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
if(memp == MAP_FAILED)
{
sys_err("mmap err");
}
strcpy(memp,"xxx"); //写操作
printf("%s\n",memp);
if(munmap(memp,4) == -1)
{
sys_err("munmap err");
}
close(fd);
return 0;
}
mmap_w.c
#include
#include
#include
#include
#include
#include
#include
#include
void sys_err(const char*str)
{
perror(str);
exit(1);
}
struct student
{
int id;
char name[256];
int age;
};
int main(int argc,char*argv[])
{
struct student stu = {1,"xiaowang",18};
int fd = open("testmap",O_RDWR|O_CREAT|O_TRUNC,0664);
ftruncate(fd,sizeof(stu));
struct student* p = mmap(NULL,sizeof(stu),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
if(p == MAP_FAILED)
{
sys_err("mmap error");
}
close(fd);
while(1)
{
memcpy(p,&stu,sizeof(stu));
stu.id++;
sleep(2);
}
munmap(p,sizeof(stu));
return 0;
}
mmap_r.c
#include
#include
#include
#include
#include
#include
#include
#include
void sys_err(const char*str)
{
perror(str);
exit(1);
}
struct student
{
int id;
char name[256];
int age;
};
int main(int argc,char*argv[])
{
struct student stu;
int fd = open("testmap",O_RDONLY);
struct student* p = mmap(NULL,sizeof(stu),PROT_READ,MAP_SHARED,fd,0);
if(p == MAP_FAILED)
{
sys_err("mmap error");
}
close(fd);
while(1)
{
printf("id = %d, name = %s, age = %d\n",p->id,p->name,p->age);
sleep(2);
}
munmap(p,sizeof(stu));
return 0;
}
无血缘关系进程间通信:
p =(int*)mmap(NULL,400,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
fd = open("/dev/zero",O_RDWR);
p = mmap(NULL,size.PROT_READ|PROT_WRITE,MMAP_SHARED,fd,0);