首页 > 系统相关 >Linux 7种 进程间通信方式

Linux 7种 进程间通信方式

时间:2024-06-23 21:56:20浏览次数:3  
标签:int pipefd 间通信 管道 Linux 进程 sizeof buff

传统进程间通信

        通过文件实现进程间通信 必须人为保证先后顺序        A--->硬盘---> B(B不知道A什么时候把内容传到硬盘中)

1.无名管道

2.有名管道

3.信号

IPC进程间通信

4.消息队列

5.共享内存

6.信号灯集

7.socket通信

一、无名管道(亲缘关系的进程   64K)

原理:

        如果A和B进程想要通过无名管道通信,那就必须在内核空间创建一个无名管道(64K),A和B进程必须是亲缘关系的进程,A进程向管道的一端写数据,B进程可以从管道的另外一端读数据。在A进程和B进程进行数据传输的时候是不允许使用lseek函数的。无名管道是半双工的通信方式。如果A进程一直向管道中写数据写满64K的时候A进程阻塞,直到B进程读一部分数据之后A才能继续写。如果B进程在读数据的时候,无名管道是空的,B进程阻塞。(PS:使用无名管道时,不会创建管道文件,使用有名管道文件,会创建)

API

int pipe(int pipefd[2]);
功能:创建一个无名管道
参数:
    @pipefd[2]:返回的管道的两端
     pipefd[1]:写端
     pipefd[0]:读端
返回值:成功返回0,失败返回-1置位错误码

实例

#include <head.h>
// 子进程从终端读取字符串 通过无名管道 父进程读 然后打印到终端
int main(int argc, const char *argv[])
{
    int pipefd[2];
    if (-1 == pipe(pipefd))
    {
        perror("pipe error");
        exit(-1);
    };
    char buff[128] = {0};
    pid_t pid;
    pid = fork();
    if (pid == -1)
    {
        perror("fork error");
        exit(-1);
    }
    else if (pid == 0)
    {
        // 子进程
        close(pipefd[0]); // 关闭子进程的读端   因为父子进程同时各自拥有读和写 把对应的关一个
        while (1)
        {
            memset(buff, 0, sizeof(buff));
            fgets(buff, sizeof(buff), stdin); // 从终端读取数据
            if ((buff[strlen(buff) - 1]) == '\n')
            {
                buff[strlen(buff) - 1] = '\0';
            }
            write(pipefd[1], buff, sizeof(buff)); // 将读到的写入到管道
            if (strcmp(buff, "quit") == 0)
            {
                break;
            }
        }
        close(pipefd[1]);
        exit(0);
    }
    else
    {
        // 父进程
        close(pipefd[1]); // 关闭父进程的写端
        while (1)
        {
            memset(buff, 0, sizeof(buff));
            read(pipefd[0], buff, sizeof(buff)); // 父进程从管道中读
            printf("父进程data:%s\n", buff);
            if (strcmp(buff, "quit") == 0)
            {
                break;
            }
        }
        close(pipefd[2]);
        wait(NULL);
    }
    return 0;
}

结果

二、有名管道(任意进程间的通信    64K)

有名管道可以实现任意进程间的通信,有名管道的大小也是64K,有名管道也是不支持lseek,有名管道也是半双工的通信方式。有名管道创建之后会在用户空间产生一个管道文件(p),这个管

文件是在内存上存储的。如果A和B两个进程想要通过有名管道通信,就打开管道文件,向管道中写向管道中读就可。

API

int mkfifo(const char *pathname, mode_t mode);
功能:创建有名管道
参数:
    @pathname:有名管道文件的路径及名字
 @mode: 管道文件的权限(mode & ~umask)
返回值:成功返回0,失败返回-1置位错误码

实例

01mkfifo.c

#include <head.h>
#define FIFO_PATH "./myfifo"
int main(int argc,const char * argv[])
{
    //创建管道文件
    if(mkfifo(FIFO_PATH,0666)==-1){
        perror("mkfifo error");
        exit(-1);
    }
    //阻塞等待读写
    getchar();
    //删除管道文件
    char buff[128]={0};
    snprintf(buff,sizeof(buff),"rm -rf %s",FIFO_PATH);
    system(buff);
    return 0;
}

02read.c

#include <head.h>
#define FIFO_PATH "./myfifo"
int main(int argc, const char *argv[])
{
    int fd;
    char buff[128] = {0};
    if (-1 == (fd = open(FIFO_PATH, O_RDONLY)))
    {
        perror("open error");
        exit(-1);
    }
    while (1)
    {
        memset(buff, 0, sizeof(buff));
        read(fd, buff, sizeof(buff));
        printf("read:[%s]\n", buff);
        if (strcmp(buff, "quit") == 0)
        {
            break;
        }
    }
    close(fd);
    return 0;
}

03write.c

#include <head.h>
#define FIFO_PATH "./myfifo"
int main(int argc, const char *argv[])
{
    int fd;
    char buff[128] = {0};
    if (-1 == (fd = open(FIFO_PATH, O_WRONLY)))
    {
        perror("open error");
        exit(-1);
    }
    while (1)
    {
        memset(buff, 0, sizeof(buff));
        printf("input:");
        fgets(buff,sizeof(buff),stdin);
        if(buff[strlen(buff)-1]=='\n'){
            buff[strlen(buff)-1]='\0';
        }
        write(fd, buff, sizeof(buff));
        if (strcmp(buff, "quit") == 0)
        {
            break;
        }
    }
    close(fd);
    return 0;
}

结果

 三、信号

信号软件层面对中断一种模拟,用户可以给进程发送信号,内核也可以给进程发送信号,进程对信号的响应方式有三种:捕捉,默认,忽略

标签:int,pipefd,间通信,管道,Linux,进程,sizeof,buff
From: https://blog.csdn.net/CSDN_DU666666/article/details/139904835

相关文章

  • Rocky Linux捣鼓记录(五):安装flatpak软件仓库,并更换国内源
    1、安装flatpaksudodnfinstallflatpak2、安装flatpak的官方源先安装官方仓库:注意此处命名为:flathub,这个名称是用来区分仓库的,后续修改国内源也要指定这个名称flatpakremote-add--if-not-existsflathubhttps://dl.flathub.org/repo/flathub.flatpakrepo3、更改为上海......
  • 【Linux】进程间通信_1
    文章目录七、进程间通信1.进程间通信分类管道未完待续七、进程间通信进程间由于进程具有独立性,所以不可以直接进行数据传递。但是我们通常需要多个进程协同,共同完成一件事,所以我们需要进程间通信的手段。进程间通信的本质就是先让不同的进程看到同一份资源,这个......
  • petalinux调试常用命令总结
    petalinux调试常用命令总结1.创建新的工程:zynq:petalinux-create-tproject--templatezynq--nametest_projzynqMP:petalinux-create-tproject--templatezynqMP--namezcu102-mp2.创建新的app:petalinux-create-tapps--templatec--namemyapp--enable3.创......
  • 【Linux详解】冯诺依曼架构 | 操作系统设计 | 斯坦福经典项目Pintos
    目录一.冯诺依曼体系结构(VonNeumannArchitecture)注意事项存储器的意义:缓冲数据流动示例二.操作系统(OperatingSystem)操作系统的概念操作系统的定位与目的操作系统的管理系统调用和库函数操作系统的管理:sum三.系统调用实现示例:Pintos项目Step1:进入ex......
  • Linux开发讲课12--- /proc 目录
    /proc 目录在Linux系统中是一个虚拟文件系统,它不是存储在硬盘上的常规文件系统,而是由内核在内存中动态生成的。这个目录主要用于提供系统和进程的运行时信息,它有非常多的用途,但大部分人却不懂使用。本文我将详细介绍 /proc 目录的一些主要用途。一.系统信息1.CPU信息......
  • 线程间通信方式
    1通信机制:互斥与同步线程的互斥通过线程的互斥锁完成;线程的同步通过无名信号量或者条件变量完成。2 互斥2.1何为互斥?       互斥是在多个线程在访问同一个全局变量的时候,先让这个线程争抢锁的资源,那个线程争抢到资源,它可以访问这个变量,没有争抢到资源的线程不......
  • Spdlog日志库的安装配置与源码解析(Linux)
    为什么使用日志库而不是控制台输出?日志库通常提供了更丰富的功能,比如可以设置日志输出级别、输出到不同的目标(比如控制台、文件、网络等),以及格式化输出等。使用日志库可以使代码更易于维护。通过统一的日志接口,可以更容易地对日志输出进行修改、调整和管理,而不需要在代......
  • 一问搞懂Linux信号【上】
    Linux信号在Linux系统中的地位仅此于进程间通信,其重要程度不言而喻。本文我们将从信号产生,信号保存,信号处理三个方面来讲解信号。......
  • Linux的学习与使用(进程管理)
    命令学习(一)ps命令1.ps显示当前终端会话的进程。2.psaux显示系统上所有进程的详细信息。NameDescriptionExample(图中第一行)USER进程的所有者rootPID进程ID1%CPU进程占用的CPU百分比0.2%MEM进程占用的内存百分比0.2VSZ进程使用的虚拟内存量......
  • linux 中 检测后台任务
     001、[root@PC1test2]#lstest.sh[root@PC1test2]#cattest.sh##脚本#!/bin/bashseq10000000000000000000000000000000000000&>/dev/null[root@PC1test2]#nohupbashtest.sh>log_Download2>&1&......