【IO进程线程】

本文介绍了Linux系统中进程间通信的三种方式:无名管道、有名管道和信号。详细阐述了无名管道的原理、API、特点及读写特点,有名管道的原理、API及读写特点,并详细解析了信号的工作原理、查看命令、进程处理信号的三种方式及实践示例。
摘要由CSDN通过智能技术生成

进程间通信

进程进通信简介

假如A进程和B进程想要通信,按照之间讲解的进程的原理是无法完成的,A和B进程的内存空间是独立的0-3G。如果想要实现通信就必须借助内核空间才能完成,因为内核空间是共用的。在linux系统中进程间通信的方式有7种。
(1)传统进程间通信(3种)
​ 1.无名管道
​ 2.有名管道
​ 3.信号
(2)system V版本引入IPC进程间通信(3种)
​ 1.消息队列
​ 2.共享内存
​ 3.信号灯集
(3)BSD(伯克利分校)版本中引入的socket通信
​ 1.套接字通信(通过网络实现进程间通信)
(4)Android系统中
​ 1.binder机制

无名管道

无名管道通信的原理

无名管道只能由于亲缘关系的进程间通信,无名管道是在内核中实现的。如果A和B进程想要通过无名管道通信,A向管道的一端发送消息,B进程从管道的另外一端读取消息即可。无名管道的通信方式不支持使用lseek函数。无名管道的大小是64K。如果A一直往管道中写数据,B不读取。A写满的时候就会阻塞。如果A没有写,B取读取数据,B进程阻塞。无名管道是半双工的通信方式。

A和B的通信方式:
单工: A------------->B
半双工:在同一时刻内只能一边发一边收
​ A------>B A<-------B
全双工:在同一时刻两边都可以收发
​ A<-------->B
在这里插入图片描述

无名管道的API

int pipe(int pipefd[2]);
功能:Pipe()创建一个管道,这是一个可以用于进程间通信的单向数据通道。
    数组pipefd用于返回引用管道两端的两个文件描述符。Pipefd [0]是指
    管道的读端。Pipefd[1]指管道的写端。写入到管道写端的数据由内核进
    行缓冲,直到从管道读端读取。
参数:
    @pipefd :返回管道两端的文件描述符
         pipefd[0]读端
         pipefd[1]写端
返回值:成功返回0,失败返回-1置位错误码

无名管道的实例

#include <head.h>

int main(int argc, const char* argv[])
{
   
    pid_t pid;
    int pipefd[2];
    char buf[128] = {
    0 };
    // 1.创建无名管道
    if (pipe(pipefd))
        PRINT_ERR("pipe error");

    // 2.创建进程
    pid = fork();
    if (pid == -1) {
   
        PRINT_ERR("fork error");
    } else if (pid == 0) {
   
        close(pipefd[0]); // 关闭子进程的读端
        // 子进程向管道中写数据 pipefd[1]
        while (1) {
   
            fgets(buf, sizeof(buf), stdin);
            buf[strlen(buf) - 1] = '\0';

            write(pipefd[1], buf, strlen(buf));
            if (strcmp(buf, "quit") == 0)
                break;
        }
        close(pipefd[1]);
        exit(0);

    } else {
   
        close(pipefd[1]); // 关闭父进程的写端
        // 从管道中读数据 pipefd[0]
        while (1) {
   
            memset(buf, 0, sizeof(buf));
            read(pipefd[0], buf, sizeof(buf));
            if (strcmp(buf, "quit") == 0)
                break;
            printf("buf = %s\n", buf);
        }
        close(pipefd[0]);
        wait(NULL);
    }
    return 0;
}

无名管道的特点

1.只能用于亲缘关系的进程的通信
2.无名管道是半双工的通信方式
3.不支持使用lseek函数
4.无名管道的大小是64K

#include <head.h>

int main(int argc, const char* argv[])
{
   
    pid_t pid;
    int pipefd[2];
    char buf[128] = {
    0 };
    // 1.创建无名管道
    if (pipe(pipefd))
        PRINT_ERR("pipe error");

   for(int i=0;i<65537;i++){
   
    write(pipefd[1],"a",1); //写第65537个字符的时候,因为管道满了,写阻塞
    printf("i = %d\n",i);
   }
   printf("********************\n"); //这句话不打印
    return 0;
}

无名管道读写的特点

读端存在,写管道 :有多少写多少,直到写满(64K)位置。
#include <head.h>

int main(int argc, const char* argv[])
{
   
    pid_t pid;
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值