【回眸】技术干货——Linux内核(十二) 进程间通讯 之 管道

​前言

进程的介绍已经告一段落,接下来学习的内容是进程间的通讯.

进程间通信(IPC)

面试考点:

IPC的通讯方式通常有:管道(无名和命名) ,消息队列,信号量,共享存储,socket,streams等.socket和streams支持2个不同的主机上的2个进程IPC.

管道通常指无名管道

特点:

  1. 半双工(只能在一个方向上流动)
  2. 只能用于具有亲缘关系的进程间通讯(父子进程or兄弟进程)
  3. 读写可用 read write 等函数,不属于其他任何文件系统,只存在于内存中.
  4. 局限性:

1.同一时间只能单向(eg:父进程读,子进程写);

2.管道数据,读完就没了

函数原型:

#include <unistd.h>int pipe(int fd[i]); 
fd[0]为读而打开 ------>关闭--------> close fd[0]
fd[1]为写而打开 ------>关闭--------> close fd[1]

无名管道函数应用:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
int main (){
    int fd[2];
    int pid ;
    char buf[128];
    if (pipe(fd) == -1){
        printf("create pipe failed!\n");
    }
    pid = fork();
    if (pid < 0){
        printf ("create child progress failed!\n");
    }
    else if(pid > 0){
        printf("this is father progress!\n");
        close(fd[0]);
        write(fd[1],"hello from father",strlen("hello from father"));
        wait(&pid);
    }
    else{
        printf("this is child progress!\n");
        close(fd[1]);
        read(fd[0],buf,128);
        printf("read from father:%s!\n",buf);
        exit(0);
    }
    return 0;
}

运行结果展示:

命名管道(FIFO)

FIFO也称命名管道,是一种文件类型.

特点

  1. FIFO 可以在无关的进程之间交换数据,与无名管道不同.
  2. FIFO 有路径名与之相关连,它以一种特殊的设备文件形式存在与文件系统中.

函数原型

#include <sys/stat.h>int mkfifo(const char* pathname,moode_t mode);
//成功返回值为0,失败返回值为-1命名管道以文件的形式存储在磁盘,所以在创建FIFO之后可以用一般的I/O函数操作它.

一般read之后都会阻塞,等读取到write内容后才会回复正常.

也可以设置成非阻塞,但是不经常用于FIFO.

有名管道函数应用:

comm3.c

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

int main(){
if (mkfifo("./file",0600) == -1 && errno!= EEXIST)
{
    printf("mkfifo failed \n");
    perror("why");
}
int fd =open ("./file",O_RDONLY);
printf ("open successfully!\n ");
return 0;
}

comm4.c

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

int main(){

int fd =open ("./file",O_WRONLY);
printf ("write open successfully!\n ");
return 0;
}

运行编译命令及运行结果展示:

 命名管道(持续收发版)

comm5.c(read)

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


int main(){
    char buf[30] = {0};
    int nread = 0;

if (mkfifo("./file",0600) == -1 && errno!= EEXIST)
{
    printf("mkfifo failed \n");
    perror("why");
}
int fd =open ("./file",O_RDONLY);
printf ("open successfully!\n ");
while(1){
nread = read(fd,buf,30);
printf("Read %d byte from fifo,context = %s \n",nread,buf);
}
close(fd);
return 0;
}

 comm6.c(write)

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

int main(){
    int cnt = 0;
    char *str = "message from fifo.";
    int fd =open ("./file",O_WRONLY);
    printf ("write open successfully!\n ");
    while(1){
        write(fd,str,strlen(str));
        sleep(1);
        cnt = cnt + 1;
        if (cnt == 5){
            break;
        }
    }

    close(fd);
    return 0;
}

 运行编译命令及运行结果参考:

上述代码是写5遍,写完后不停读取,读完之后就读不到内容了。

后记碎碎念

Linux是一个系列,可以点击专栏查看同系列的其他文章,希望能帮到屏幕前的每一位应届生往届生,该博文最初发表在CSDN上。

#租房前辈的忠告##校招求职有谈薪空间吗##找工作前vs找工作后的心路变化##26届秋招投递记录##央国企投递记录#
应届生必学实用物联网技术 文章被收录于专栏

本专栏助应届生从物联网小白成长为企业争抢的技术人才,聚焦三大核心技术:传感器应用(环境监测)、嵌入式开发(STM32/Arduino)、通信协议(LoRa/NB-IoT/MQTT),配合10+实战项目(如智能温湿度监控系统)积累项目经验。覆盖智能硬件、工业物联网、智能家居领域岗位需求,解析企业招聘技术重点与面试题,帮电子、计算机、自动化等专业学生构建知识体系,提前锁定名企Offer!

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务