IPC

 

 

 

 (read默认是阻塞的,会一直等着,直到读到,所以会打印)

实现 ps aux | grep bash

#include <stdio.h>
#include <unistd.h>

int main()
{
    int fd[2];
    pipe(fd);

    pid_t pid = fork();
    if(pid == 0){
        //son 
        //son -- > ps 
        //关闭 读端
        close(fd[0]);
        //1. 先重定向
        dup2(fd[1],STDOUT_FILENO);//标准输出重定向到管道写端
        //2. execlp 
        execlp("ps","ps","aux",NULL);
    }else if(pid > 0){
        //parent
        //关闭写端
        close(fd[1]);
        //1. 先重定向,标准输入重定向到管道读端
        dup2(fd[0],STDIN_FILENO);
        //2. execlp 
        execlp("grep","grep","bash",NULL);
    }

    return 0;
}

 

兄弟进程间通信,实现 ps aux | grep bash

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
    int fd[2];
    pipe(fd);
    pid_t pid;
    int n =2,i = 0;
    for(i = 0; i < n ; i ++){
        pid = fork();
        if(pid == 0){
            break;
        }
    }

    //i = 0 ,代表兄长,1 - 代表弟弟,2- 父亲
    if(i == 0){
        //兄长进程
        //1. 关闭读端
        close(fd[0]);
        //2. 重定向
        dup2(fd[1],STDOUT_FILENO);
        //3. 执行 execlp
        execlp("ps","ps","aux",NULL);
            
    }else if(i == 1){
        //弟弟 
        //1. 关闭写端
        close(fd[1]);
        //2. 重定向
        dup2(fd[0],STDIN_FILENO);
        //3. 执行ececlp
        execlp("grep","grep","bash",NULL);

    }else if(i == 2){
        //parent 
        //父亲需要关闭读写两端
        close(fd[0]);
        close(fd[1]);
        //回收子进程
        wait(NULL);
        wait(NULL);
    }


    return 0;
}

FiFO

 

 写端:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

int main(int argc,char * argv[])
{
    if(argc != 2){
        printf("./a.out fifoname
");
        return -1;
    }
    
    // 当前目录有一个 myfifo 文件
    //打开fifo文件
    printf("begin open ....
");
    int fd = open(argv[1],O_WRONLY);
    printf("end open ....
");
    //
    char buf[256];
    int num = 1;
    while(1){
        memset(buf,0x00,sizeof(buf));
        sprintf(buf,"xiaoming%04d",num++);
        write(fd,buf,strlen(buf));
        sleep(1);
        //循环写
    }
    //关闭描述符
    close(fd);
    return 0;
}

读端:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

int main(int argc,char *argv[])
{
    if(argc != 2){
        printf("./a.out fifoname
");
        return -1;
    }
    printf("begin oepn read...
");
    int fd = open(argv[1],O_RDONLY);
    printf("end oepn read...
");
    
    char buf[256];
    int ret;
    while(1){
        //循环读
        memset(buf,0x00,sizeof(buf));
        ret = read(fd,buf,sizeof(buf));
        if(ret > 0){
            printf("read:%s
",buf);
        }
    }

    close(fd);
    return 0;
}

mmap

 

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>

int main()
{
    int fd = open("mem.txt",O_RDWR);//创建并且截断文件
    //int fd = open("mem.txt",O_RDWR|O_CREAT|O_TRUNC,0664);//创建并且截断文件

    ftruncate(fd,8);   
    //创建映射区
   char *mem = mmap(NULL,20,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);  //文件只有8,此处20,也只会写8个
    //char *mem = mmap(NULL,8,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,0);  //private 不会更改源文件 

    if(mem == MAP_FAILED){
        perror("mmap err");
        return -1;
    }
    close(fd);
    //拷贝数据
    strcpy(mem,"helloworld");
//    mem++;  若更改地址,munmap会报错   
    //释放mmap
    if(munmap(mem,20) < 0){
        perror("munmap err");
    }
    return 0;
}

 

 

 

 

 

 匿名映射无法实现无血缘关系进程间通信!

无血缘例子

写:

#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>

typedef struct _Student{
    int sid;
    char sname[20];
}Student;

int main(int argc, char* argv[]){
    if(argc!=2){
        printf("need filename
");
        return -1;
    }
    int fd=open(argv[1],O_RDWR|O_CREAT|O_TRUNC,0666);
    int length=sizeof(Student);
    ftruncate(fd,length);
    
    Student* stu=mmap(NULL,length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    if(stu==MAP_FAILED){
        perror("mmp err");
        return -1;
    }

    int num=1;
    while(1){
        stu->sid=num;
        sprintf(stu->sname,"xiaoming-%03d",num++);
        sleep(1);
    }
    
    munmap(stu,length);
    close(fd);
    return 0;
}

读:

#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>

typedef struct _Student{
    int sid;
    char sname[20];
}Student;

int main(int argc, char* argv[]){
    int fd=open(argv[1],O_RDWR);
    
    int length=sizeof(Student);
    Student* stu=mmap(NULL,length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    if(stu==MAP_FAILED){
        perror("mmap err");
        return -1;
    }

    while(1){
        printf("sid=%d, sname=%s
", stu->sid, stu->sname);
        sleep(1);
    }
    
    munmap(stu,length);
    close(fd);

    return 0;
}

 (文件作为媒介)

多进程拷贝文件:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char* argv[])
{
    int n=5;
    if(argc<3){
        printf("need file name
");
        return -1;
    }

    int srcfd=open(argv[1],O_RDONLY);
    if(srcfd<0){
        perror("open err");
        exit(1);
    }
    int dstfd=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0664);
    if(dstfd<0){
        perror("open err");
        exit(1);
    }

    struct stat sb;
    stat(argv[1], &sb);
    int len=sb.st_size;
    truncate(argv[2],len);

    char *psrc=mmap(NULL,len,PROT_READ,MAP_SHARED,srcfd,0);
    if(psrc==MAP_FAILED){
        perror("mmap src err");
        exit(1);
    }

    char *pdst=mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,dstfd,0);
    if(pdst==MAP_FAILED){
        perror("mmap dst err");
        exit(1);
    }

    int i=0;
    for(i=0;i<n;i++){
        pid_t pid=fork();
        if(pid==0) break;
    }

    int cpsize=len/n;
    int mod=len%n;
    if(i<n){
        if(i==n-1){
            memcpy(pdst+i*cpsize, psrc+i*cpsize, cpsize+mod);
        }
        else{
            memcpy(pdst+i*cpsize, psrc+i*cpsize, cpsize);
        }
    }else{
        int i=0;
        for(i=0;i<n;i++){
            wait(NULL);
        }

        if(munmap(psrc,len)<0){
            perror("munmap src err");
            exit(1);
        }

        if(munmap(pdst,len)<0){
            perror("munmap dst err");
            exit(1);
        }

        close(srcfd);
        close(dstfd);
    }



    return 0;
}
原文地址:https://www.cnblogs.com/FEIIEF/p/12449790.html