美文网首页
Linux进程之间通信

Linux进程之间通信

作者: 小小混世魔王 | 来源:发表于2019-05-25 19:51 被阅读0次

    上篇文章了解到Linux平台下编译静态库和动态库并了解到链接的原理。https://www.jianshu.com/p/020b341d3c2b 这篇文章来了解一些进程方面的知识。
    进程是程序运行的活动,是系统进行资源分配和调度的基本单位。简单的来看一个正在运行的程序就是一个进程。进程包含的数据有程序可运行机器码映像。映像加载到虚拟内存的 。内存的内容包括可运行代码、特定于进程的数据(输入、输出)、调用堆栈、堆栈(用于保存运行时运数中途产生的数据)。 分配给该进程的资源的操作系统描述符,如文件描述或文件句柄等。进程也类似线程存在状态的,由内核pcb进程控制块来控制进程的状态。

    进程之间通信

    为了安全系统设计进程之间的数据是不可以共享的,有时又需要访问另一个进程的数据。就需要进程之间的通信。
    利用管道通信:
    管道可以看成是一个特殊的文件,它不占磁盘空间,占用的是内存,所以我们直接可以read 和write数据。由于管道是半双工数据传输,数据只能单向流通,读写数据是不能够同时进行的。而且只限于有血缘关系(父子,兄弟进程)的进程之间的通信。
    通过fork函数创建子线程看看他们是怎么通信的。

    #include<stdio.h>
    #include<unistd.h>
    
    //父进程向子线程 写东西
    int main() {
            int fd[2];
            int ret = pipe(fd);
            if(ret != 0) {
                    printf("crate pipe fail\n");
                    return -1;
            }
            pid_t pid = fork();
            if(pid < 0) {
                    printf("fork process fail\n");
                    return -1;
            } else if(pid == 0){
                    sleep(2);
                    printf("Im child process\n");
                    close(fd[1]);
                    char buf[11];
                    read(fd[0],buf,11);
                    printf("输出:%s",buf);
            }else{
                    printf("Im parent process\n");
                    close(fd[0]);
                    write(fd[1],"hello world",11);
            }
            return 0;
    }
    

    信号:
    进程之间可以通过信号来进行通信,信号是内核自带的传递携带数据量不大,一般携带一个数字作为处理的信号。在pcb进程控制块中包含有信号屏蔽字与未决信号集。信号的产生有系统调用kill , raise, abort等函数,包括硬件的异常,访问了非法内存等都会产生信号。信号的处理方式,系统可以忽略 捕获 执行系统默认活动,android应用出现异常退出系统接收到信息执行了默认的活动程序才退出的。包括进程的杀死的都是通过系统接收信号来执行的。pcb进程控制块中的信号屏蔽字是用来屏蔽某个型号的,一个型号发送是发送到pcb进程控制块中的未决信号集中的,系统执行信号时需要查看该信号是否屏蔽。
    共享映射区:

    共享映射区是基于文件来实现的,并不是普通的文件读写来通信的,普通的文件读写是要通过用户空间写入内核区,另一个进程读取需要从内核读取到用户的空间实现数据的通信,数据经历了两次拷贝。共享映射区通信方式只要通过一次数据的拷贝,而且还不要经过内核,用户空间进入内核是一个比较缓慢过程,不要轻易的进入内核。共享映射区的原理是通过虚拟内存映射一个文件的区域,通过操作映射的内存就能够操作文件。 共享映射区.png

    看看具体的代码实现

    写端
    #include<stdio.h>
    #include<unistd.h>
    #include<sys/mman.h>
    #include<fcntl.h>
    #include<string.h>
    int main() {
            int fd = open("mmapipc",O_RDWR | O_CREAT | O_TRUNC, 0644);
            ftruncate(fd, 13);
            if(fd == -1) {
                    printf("open fail \n");
                    return -1;
            }
            char* writecontent =(char*) mmap(NULL,13,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
            if(writecontent == MAP_FAILED) {
    
                    printf("映射失败");
                    return -1;
            }
            while(1){
                    sleep(1);
                    memcpy(writecontent, "hello", 5);
            }
    
            return 0;
    }
       
    
    读端
    #include<stdio.h>
    #include<string.h>
    #include<unistd.h>
    #include<sys/mman.h>
    #include <fcntl.h>
    
    int main(){
            char *pathname = "mmapipc";
            int fd = open(pathname,O_RDONLY);
            if(fd == -1) {
    
                    printf("open file fail\n");
                    return -1;
            }
    
            char* readIpc =(char*)mmap(NULL,11,PROT_READ, MAP_SHARED, fd, 0);
    
            if(readIpc == MAP_FAILED) {
                    printf("open file fail\n");
                    return -1;
            }
    
            while (1){
                    printf("%s",readIpc);
            }
    
            return 0;
    }
    
    
    小结:

    Linux进程之间的通信还有套接字的方式,这里不去了解,关于进程知识,包括怎么fork子进程,什么是孤儿进程,僵尸进程,守护进程,包括虚拟内存有兴趣可以了解了解。

    相关文章

      网友评论

          本文标题:Linux进程之间通信

          本文链接:https://www.haomeiwen.com/subject/guzzaqtx.html