当前位置: 首页 > article >正文

进程间通信的七种方法实战演示!值得收藏!

文章目录

  • 前言
  • 一、管道(Pipes)
    • 管道示例代码:
    • 管道示例流程解读:
    • 管道示例运行效果:
  • 二、消息队列(Message Queues)
    • 消息队列示例代码
    • 消息队列示例流程解读:
    • 消息队列示例执行效果
  • 三、共享内存(Shared Memory)
    • 共享内存示例代码
    • 共享内存示例流程解读:
    • 共享内存示例执行效果
  • 四、 信号(Signals)
    • 信号示例代码:
    • 信号示例流程解读:
    • 信号示例执行效果
  • 五、套接字(Sockets)
    • 套接字示例代码:
    • 套接字示例流程解读:
    • 套接字示例执行结果
  • 六、信号量(Semaphores)
    • 信号量示例代码:
    • 信号量示例流程解读:
    • 信号量示例执行结果
  • 七、文件映射(Memory-Mapped Files)
    • 文件映射示例代码:
    • 文件映射示例流程解读:
    • 文件映射示例执行结果
  • 总结


前言

线程和进程间的通讯(Inter-Process Communication, IPC)是操作系统中的一个重要概念,用于实现不同进程或同一进程中的不同线程之间的数据交换和协调。
但是这些概念太多了,容易搞混了,所有特地写了这篇博客来记录这些方式的使用实例,建立大家收藏起来,将来需要复习的时候,再来看一看,能够快速的带你复习一遍!

以下是几个常见的进程间通信的方式:管道、消息队列、共享内存、信号、套接字、信号量、文件映射


提示:以下是本篇文章正文内容,下面案例可供参考

一、管道(Pipes)

管道是一种半双工的通信方式,数据只能单向流动。管道分为两种类型:

匿名管道:仅限于具有亲缘关系的进程之间使用,通常用于父子进程之间的通信。
命名管道(FIFO):可以在任意两个进程之间使用,通过文件系统中的一个特殊文件来标识。

管道示例代码:

以下是一个简单的 C 语言示例,演示如何使用管道实现父子进程间的通信。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h> // 用于 memset

int main() {
    int pipefd[2];
    pid_t pid;
    char buf[100];

    if (pipe(pipefd) == -1) {
        perror("pipe");
        return 1;
    }

    pid = fork();
    if (pid == -1) {
        perror("fork");
        return 1;
    }

    if (pid == 0) { // 子进程
        close(pipefd[0]); // 关闭读端
        write(pipefd[1], "Hello from child", 18);
        close(pipefd[1]);
    } else { // 父进程
        close(pipefd[1]); // 关闭写端
        memset(buf, 0, sizeof(buf)); // 清空缓冲区
        ssize_t bytes_read = read(pipefd[0], buf, sizeof(buf) - 1); // 读取数据,留一个字节给终止符
        if (bytes_read > 0) {
            printf("Received: %s\n", buf);
        } else {
            perror("read");
        }
        close(pipefd[0]);
        wait(NULL);
    }

    return 0;
}

管道示例流程解读:

1、创建管道:使用 pipe 函数创建一个管道,该函数返回两个文件描述符,分别用于读取和写入。

2、创建子进程:使用 fork 函数创建一个子进程。fork 返回子进程的 PID,如果返回值为 -1 表示出错,0 表示当前是子进程,其他值表示当前是父进程。

3、关闭不必要的管道端:
在父进程中,关闭管道的端(pipefd[1]),因为子进程只读取数据。
在子进程中,关闭管道的读端(pipefd[0]),因为父进程只写入数据。

4、数据传输:
子进程使用 write 函数向管道中写入数据。
父进程使用 read 函数从管道中读取数据。

5、关闭管道:在完成数据传输后,关闭管道的相应端。

6、等待子进程结束:父进程使用 wait 函数等待子进程结束。

管道示例运行效果:

在这里插入图片描述

二、消息队列(Message Queues)

消息队列是一种更高级的通信方式,允许进程发送和接收消息。消息队列可以存储多个消息,并且可以设置消息的优先级。

消息队列示例代码

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

#define MAX_MSG_SIZE 256

// 定义消息结构体
struct msg_buffer {
    long msg_type;
    char msg_text[MAX_MSG_SIZE];
};

int main() {
    key_t key;
    int msgid;
    struct msg_buffer message;
    pid_t cpid;

    // 生成一个唯一的键值
    key = ftok("/etc/passwd", 65); // 使用现有的文件 /etc/passwd
    if (key == -1) {
        perror("ftok");
        exit(EXIT_FAILURE);
    }

    // 创建消息队列
    msgid = msgget(key, 0666 | IPC_CREAT);
    if (msgid == -1) {
        perror("msgget");
        exit(EXIT_FAILURE);
    }

    // 创建子进程
    cpid = fork();

    if (cpid == -1) { // fork 失败
        perror("fork");
        exit(EXIT_FAILURE);
    } else if (cpid == 0) { // 子进程
        // 子进程接收消息
        if (msgrcv(msgid, &message, sizeof(message.msg_text), 1, 0) == -1) {
            perror("msgrcv");
            exit(EXIT_FAILURE);
        }
        printf("Child process received: %s\n", message.msg_text);

        // 子进程发送消息
        message.msg_type = 2;
        strcpy(message.msg_text, "Hello from child");
        if (msgsnd(msgid, &message, sizeof(message.msg_text), 0) == -1) {
            perror("msgsnd");
            exit(EXIT_FAILURE);
        }

        exit(EXIT_SUCCESS);
    } else { // 父进程
        // 父进程发送消息
        message.msg_type = 1;
        strcpy(message.msg_text, "Hello from parent");
        if (msgsnd(msgid, &message, sizeof(message.msg_text), 0) == -1) {
            perror("msgsnd");
            exit(EXIT_FAILURE);
        }

        // 父进程接收消息
        if (msgrcv(msgid, &message, sizeof(message.msg_text), 2, 0) == -1) {
            perror("msgrcv");
            exit(EXIT_FAILURE);
        }
        printf("Parent process received: %s\n", message.msg_text);

        // 等待子进程结束
        wait(NULL);

        // 删除消息队列
        if (msgctl(msgid, IPC_RMID, NULL) == -1) {
            perror("msgctl");
            exit(EXIT_FAILURE);
        }
    }

    return 0;
}

消息队列示例流程解读:

1、生成唯一键值:使用 ftok 函数生成一个唯一的键值,这个键值用于创建消息队列。这里需要指定一个文件

2、创建消息队列:使用 msgget 函数创建一个消息队列。0666 | IPC_CREAT 表示创建一个新的消息队列,并设置权限。

3、创建子进程:使用 fork 函数创建一个子进程。

4、父进程发送消息:
设置消息类型为 1。
使用 msgsnd 函数将消息发送到消息队列。

5、子进程接收消息:
使用 msgrcv 函数从消息队列中接收类型为 1 的消息。
打印接收到的消息。
设置消息类型为 2。
使用 msgsnd 函数将消息发送回父进程。

6、父进程接收子进程的消息:
使用 msgrcv 函数从消息队列中接收类型为 2 的消息。
打印接收到的消息。

7、删除消息队列:使用 msgctl 函数删除消息队列。

消息队列示例执行效果

在这里插入图片描述

三、共享内存(Shared Memory)

共享内存允许多个进程共享同一块内存区域,是最快速的进程间通信方式。但是需要同步机制(如信号量)来防止竞态条件。

共享内存示例代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/wait.h>

#define SHM_SIZE 1024  // 共享内存大小

int main() {
    key_t key;
    int shmid;
    char *shm;
    pid_t cpid;

    // 生成一个唯一的键值
    key = ftok("progfile", 65);
    if (key == -1) {
        perror("ftok");
        exit(EXIT_FAILURE);
    }

    // 创建共享内存段
    shmid = shmget(key, SHM_SIZE, 0666 | IPC_CREAT);
    if (shmid == -1) {
        perror("shmget");
        exit(EXIT_FAILURE);
    }
    // 将共享内存段连接到进程地址空间
    shm = shmat(shmid, NULL, 0);
    if (shm == (char *) -1) {
        perror("shmat");
        exit(EXIT_FAILURE);
    }
    // 创建子进程
    cpid = fork();

    if (cpid == -1) { // fork 失败
        perror("fork");
        exit(EXIT_FAILURE);
    } else if (cpid == 0) { // 子进程
        // 子进程读取共享内存中的数据
        printf("Child process reads: %s\n", shm);

        // 子进程写入共享内存
        strcpy(shm, "Hello from child");

        // 子进程断开共享内存
        if (shmdt(shm) == -1) {
            perror("shmdt");
            exit(EXIT_FAILURE);
        }
        exit(EXIT_SUCCESS);
    } else { // 父进程
        // 父进程写入共享内存
        strcpy(shm, "Hello from parent");

        // 父进程等待子进程结束
        wait(NULL);

        // 父进程读取共享内存中的数据
        printf("Parent process reads: %s\n", shm);

        // 父进程断开共享内存
        if (shmdt(shm) == -1) {
            perror("shmdt");
            exit(EXIT_FAILURE);
        }

        // 删除共享内存段
        if (shmctl(shmid, IPC_RMID, NULL) == -1) {
            perror("shmctl");
            exit(EXIT_FAILURE);
        }
    }

    return 0;
}

共享内存示例流程解读:

1、生成唯一键值:使用 ftok 函数生成一个唯一的键值,这个键值用于创建共享内存段。

2、创建共享内存段:使用 shmget 函数创建一个共享内存段。0666 | IPC_CREAT 表示创建一个新的共享内存段,并设置权限。

3、将共享内存段连接到进程地址空间:使用 shmat 函数将共享内存段连接到进程的地址空间。

4、创建子进程:使用 fork 函数创建一个子进程。

5、父进程写入共享内存:
父进程将消息 “Hello from parent” 写入共享内存。

6、子进程读取和写入共享内存:
子进程读取共享内存中的消息并打印。
子进程将消息 “Hello from child” 写入共享内存。

7、父进程读取子进程写入的消息:
父进程等待子进程结束。
父进程读取共享内存中的消息并打印。

8、断开共享内存:使用 shmdt 函数断开共享内存段。

9、删除共享内存段:使用 shmctl 函数删除共享内存段。

共享内存示例执行效果

在这里插入图片描述

四、 信号(Signals)

信号是一种异步通信方式,用于通知进程发生了某些事件。信号可以由操作系统或进程自身发送。

信号示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>

// 信号处理函数
void signal_handler(int signum) {
    if (signum == SIGUSR1) {
        printf("Received SIGUSR1 signal\n");
    } else if (signum == SIGUSR2) {
        printf("Received SIGUSR2 signal\n");
    }
}

int main() {
    pid_t cpid;
    struct sigaction sa;

    // 设置信号处理函数
    sa.sa_handler = signal_handler;
    sa.sa_flags = 0;
    sigemptyset(&sa.sa_mask);

    if (sigaction(SIGUSR1, &sa, NULL) == -1) {
        perror("sigaction SIGUSR1");
        exit(EXIT_FAILURE);
    }

    if (sigaction(SIGUSR2, &sa, NULL) == -1) {
        perror("sigaction SIGUSR2");
        exit(EXIT_FAILURE);
    }

    // 创建子进程
    cpid = fork();

    if (cpid == -1) { // fork 失败
        perror("fork");
        exit(EXIT_FAILURE);
    } else if (cpid == 0) { // 子进程
        // 子进程等待一段时间,让父进程先发送信号
        sleep(1);

        // 子进程发送 SIGUSR1 信号给父进程
        kill(getppid(), SIGUSR1);

        // 子进程等待一段时间,让父进程处理信号
        sleep(1);

        // 子进程发送 SIGUSR2 信号给父进程
        kill(getppid(), SIGUSR2);

        exit(EXIT_SUCCESS);
    } else { // 父进程
        // 父进程发送 SIGUSR1 信号给子进程
        kill(cpid, SIGUSR1);

        // 父进程等待一段时间,让子进程处理信号
        sleep(1);

        // 父进程发送 SIGUSR2 信号给子进程
        kill(cpid, SIGUSR2);

        // 父进程等待子进程结束
        wait(NULL);
    }

    return 0;
}

信号示例流程解读:

设置信号处理函数:
使用 sigaction 函数设置信号处理函数 signal_handler,处理 SIGUSR1 和 SIGUSR2 信号。
创建子进程:
使用 fork 函数创建一个子进程。
父进程发送信号:
父进程使用 kill 函数发送 SIGUSR1 信号给子进程。
父进程等待一段时间,让子进程处理信号。
父进程再次使用 kill 函数发送 SIGUSR2 信号给子进程。
子进程发送信号:
子进程等待一段时间,让父进程先发送信号。
子进程使用 kill 函数发送 SIGUSR1 信号给父进程。
子进程等待一段时间,让父进程处理信号。
子进程再次使用 kill 函数发送 SIGUSR2 信号给父进程。
父进程等待子进程结束:
使用 wait 函数等待子进程结束。

信号示例执行效果

在这里插入图片描述

五、套接字(Sockets)

套接字是一种网络通信方式,允许不同主机上的进程进行通信。套接字可以用于本地进程间通信(通过Unix域套接字)和远程进程间通信(通过Internet域套接字)。

套接字示例代码:

以下是一个使用套接字在父进程和子进程之间进行通信的示例。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/wait.h> 

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int server_fd, new_socket, valread;
    struct sockaddr_in address;
    int addrlen = sizeof(address);
    char buffer[BUFFER_SIZE] = {0};
    char *hello = "Hello from server";

    // 创建套接字
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // 绑定套接字
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("bind failed");
        close(server_fd);
        exit(EXIT_FAILURE);
    }

    // 监听套接字
    if (listen(server_fd, 3) < 0) {
        perror("listen");
        close(server_fd);
        exit(EXIT_FAILURE);
    }

    // 创建子进程
    pid_t cpid = fork();

    if (cpid == -1) { // fork 失败
        perror("fork");
        close(server_fd);
        exit(EXIT_FAILURE);
    } else if (cpid == 0) { // 子进程
        // 子进程作为客户端
        struct sockaddr_in serv_addr;
        int sock = 0;

        if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
            perror("socket");
            exit(EXIT_FAILURE);
        }

        serv_addr.sin_family = AF_INET;
        serv_addr.sin_port = htons(PORT);
        inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);  // 显式指定服务器 IP 地址

        // 连接到服务器
        if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
            perror("connect");
            close(sock);
            exit(EXIT_FAILURE);
        }

        // 发送消息
        send(sock, "Hello from client", strlen("Hello from client"), 0);

        // 接收消息
        valread = read(sock, buffer, BUFFER_SIZE);
        printf("Message received from server: %s\n", buffer);

        // 关闭套接字
        close(sock);

        exit(EXIT_SUCCESS);
    } else { // 父进程
        // 父进程作为服务器
        if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
            perror("accept");
            close(server_fd);
            exit(EXIT_FAILURE);
        }

        // 接收消息
        valread = read(new_socket, buffer, BUFFER_SIZE);
        printf("Message received from client: %s\n", buffer);

        // 发送消息
        send(new_socket, hello, strlen(hello), 0);

        // 关闭套接字
        close(new_socket);
        close(server_fd);

        // 等待子进程结束
        wait(NULL);
    }

    return 0;
}

套接字示例流程解读:

1、创建套接字:父进程创建一个 TCP 套接字。

2、绑定套接字:父进程将套接字绑定到本地地址和端口。

3、监听套接字:父进程将套接字设置为监听状态,等待客户端连接。

4、创建子进程:父进程创建一个子进程。

5、子进程作为客户端:
子进程创建一个新的 TCP 套接字。
子进程连接到父进程的服务器。
子进程发送消息 “Hello from client” 到服务器。
子进程接收服务器的消息并打印。
子进程关闭套接字并退出。

6、父进程作为服务器:
父进程接受客户端的连接请求。
父进程接收客户端的消息并打印。
父进程发送消息 “Hello from server” 到客户端。
父进程关闭套接字并等待子进程结束。

套接字示例执行结果

在这里插入图片描述

六、信号量(Semaphores)

信号量是一种用于控制对共享资源访问的同步机制。它可以用于进程间的同步和互斥。

信号量示例代码:

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

#define SEM_NAME "/my_semaphore"
#define SHARED_FILE "shared_file.txt"

int main() {
    sem_t *sem;
    int fd;
    pid_t pid;

    // 创建信号量
    sem = sem_open(SEM_NAME, O_CREAT, 0644, 1);
    if (sem == SEM_FAILED) {
        perror("sem_open");
        exit(EXIT_FAILURE);
    }

    // 创建共享文件
    fd = open(SHARED_FILE, O_CREAT | O_RDWR, 0666);
    if (fd == -1) {
        perror("open");
        sem_close(sem);
        sem_unlink(SEM_NAME);
        exit(EXIT_FAILURE);
    }
    close(fd);

    // 创建子进程
    pid = fork();
    if (pid == -1) {
        perror("fork");
        sem_close(sem);
        sem_unlink(SEM_NAME);
        exit(EXIT_FAILURE);
    } else if (pid == 0) { // 子进程
        // 子进程写入共享文件
        fd = open(SHARED_FILE, O_WRONLY);
        if (fd == -1) {
            perror("open");
            sem_close(sem);
            sem_unlink(SEM_NAME);
            exit(EXIT_FAILURE);
        }

        // 等待信号量
        if (sem_wait(sem) == -1) {
            perror("sem_wait");
            close(fd);
            sem_close(sem);
            sem_unlink(SEM_NAME);
            exit(EXIT_FAILURE);
        }

        // 写入消息
        const char *msg = "Hello from child";
        write(fd, msg, strlen(msg));
        printf("Child: Wrote message to shared file\n");

        // 释放信号量
        if (sem_post(sem) == -1) {
            perror("sem_post");
            close(fd);
            sem_close(sem);
            sem_unlink(SEM_NAME);
            exit(EXIT_FAILURE);
        }

        close(fd);
        exit(EXIT_SUCCESS);
    } else { // 父进程
        // 父进程读取共享文件
        fd = open(SHARED_FILE, O_RDONLY);
        if (fd == -1) {
            perror("open");
            sem_close(sem);
            sem_unlink(SEM_NAME);
            exit(EXIT_FAILURE);
        }

        // 等待信号量
        if (sem_wait(sem) == -1) {
            perror("sem_wait");
            close(fd);
            sem_close(sem);
            sem_unlink(SEM_NAME);
            exit(EXIT_FAILURE);
        }

        // 重置文件偏移量到文件开头
        lseek(fd, 0, SEEK_SET);

        // 读取消息
        char buffer[1024];
        ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);
        if (bytes_read == -1) {
            perror("read");
            close(fd);
            sem_close(sem);
            sem_unlink(SEM_NAME);
            exit(EXIT_FAILURE);
        }
        buffer[bytes_read] = '\0';
        printf("Parent: Read message from shared file: %s\n", buffer);

        // 释放信号量
        if (sem_post(sem) == -1) {
            perror("sem_post");
            close(fd);
            sem_close(sem);
            sem_unlink(SEM_NAME);
            exit(EXIT_FAILURE);
        }

        close(fd);

        // 等待子进程结束
        wait(NULL);

        // 关闭信号量
        sem_close(sem);
        sem_unlink(SEM_NAME);
    }

    return 0;
}

信号量示例流程解读:

1、创建信号量:使用 sem_open 函数创建一个命名信号量 SEM_NAME,初始值为 1。

2、创建共享文件:使用 open 函数创建一个共享文件 SHARED_FILE,如果文件已存在则打开它。

3、创建子进程:使用 fork 函数创建一个子进程。

4、子进程写入共享文件:
子进程打开共享文件,准备写入。
使用 sem_wait 函数等待信号量,确保只有一个进程可以访问共享文件。
写入消息 “Hello from child” 到共享文件。
使用 sem_post 函数释放信号量。
关闭文件并退出子进程。

5、父进程读取共享文件:
父进程打开共享文件,准备读取。
使用 sem_wait 函数等待信号量,确保只有一个进程可以访问共享文件。
重置文件偏移量到文件开头。
读取共享文件中的消息并打印。
使用 sem_post 函数释放信号量。
关闭文件,等待子进程结束,关闭信号量并删除信号量。

信号量示例执行结果

在这里插入图片描述

七、文件映射(Memory-Mapped Files)

文件映射允许将文件或文件的一部分映射到内存中,从而允许多个进程共享同一块内存区域。这在处理大文件时特别有用。

文件映射示例代码:

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

#define SHARED_FILE "shared_file.txt"
#define MMAP_SIZE 1024

int main() {
    int fd;
    pid_t pid;
    char *mapped_memory;

    // 创建共享文件
    fd = open(SHARED_FILE, O_CREAT | O_RDWR, 0666);
    if (fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }

    // 设置文件大小
    if (ftruncate(fd, MMAP_SIZE) == -1) {
        perror("ftruncate");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 映射文件到内存
    mapped_memory = mmap(NULL, MMAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (mapped_memory == MAP_FAILED) {
        perror("mmap");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 创建子进程
    pid = fork();
    if (pid == -1) {
        perror("fork");
        munmap(mapped_memory, MMAP_SIZE);
        close(fd);
        exit(EXIT_FAILURE);
    } else if (pid == 0) { // 子进程
        // 子进程写入共享内存
        const char *msg = "Hello from child";
        strcpy(mapped_memory, msg);
        printf("Child: Wrote message to shared memory: %s\n", mapped_memory);

        // 等待一段时间,让父进程有时间读取
        sleep(1);

        exit(EXIT_SUCCESS);
    } else { // 父进程
        // 父进程读取共享内存
        sleep(1); // 等待子进程写入
        printf("Parent: Read message from shared memory: %s\n", mapped_memory);

        // 等待子进程结束
        wait(NULL);

        // 取消内存映射
        if (munmap(mapped_memory, MMAP_SIZE) == -1) {
            perror("munmap");
            close(fd);
            exit(EXIT_FAILURE);
        }

        // 关闭文件
        close(fd);

        // 删除共享文件
        unlink(SHARED_FILE);
    }

    return 0;
}

文件映射示例流程解读:

1、创建共享文件:使用 open 和 ftruncate 函数创建并设置共享文件的大小。

2、映射文件到内存:使用 mmap 函数将文件映射到内存区域。

3、创建子进程:使用 fork 函数创建一个子进程。

4、子进程写入共享内存:子进程将消息写入共享内存区域,并打印写入的消息。

5、父进程读取共享内存:父进程读取共享内存区域中的消息并打印,等待子进程结束,取消内存映射,关闭文件并删除共享文件。

文件映射示例执行结果

在这里插入图片描述


总结

管道:适用于父子进程间的简单通信。

消息队列:适用于需要发送和接收消息的场景。

共享内存:适用于需要高效共享大量数据的场景。

信号:适用于异步事件的通知。

套接字:适用于网络通信和本地进程间通信。

信号量:适用于进程间的同步和互斥。

文件映射:适用于处理大文件和共享内存。


http://www.kler.cn/news/314007.html

相关文章:

  • Matlab求解微分方程(解析解与数值解)
  • 利士策分享,华为三折叠手机:重塑未来科技生活的里程碑
  • 【高等代数笔记】线性空间(五-九)
  • module ‘urllib.request‘ has no attribute ‘urlencode‘ 问题解决
  • LeetCode2414题: 最长的字母序连续子字符串的长度(原创)
  • 【数据结构-差分】力扣1589. 所有排列中的最大和
  • 十三、SOA(企业服务总线ESB架构实现)
  • JVM 一个对象是否已经死亡?
  • Invalid Private Key, Not a valid string or uint8Array
  • jQuery国内大厂CDN加速链接
  • 741. 摘樱桃
  • JVM 案例研究与实战经验
  • 硬件工程师笔试面试——滤波器
  • IntelliJ IDEA 2024创建Java项目
  • 红帽 Quay- 配置镜像代理缓存
  • 记一次安装discuz时遇到的错误
  • descrTable常用方法
  • 利士策分享,自我和解:通往赚钱与内心富足的和谐之道
  • Leetcode—移除元素
  • 海外问卷调查:选择静态IP还是动态IP?
  • Python数据分析案例59——基于图神经网络的反欺诈交易检测(GCN,GAT,GIN)
  • Redis中Hash(哈希)类型的基本操作
  • 「已解决」KeyError: ‘getpwuid(): uid not found: 1004‘
  • 编写函数,对字符数组中的字母由大到小的字母顺序进行排序
  • Jira Cloud涨价5%-20%,钉钉项目Teambition成优选替代
  • 使用Microsoft Visual Studio Installer Projects 2022打包桌面程序
  • 【大数据】MapReduce的“内存增强版”——Spark
  • 基于对数变换的图像美白增强,Matlab实现
  • Docker 数据目录迁移:一篇详细的技术指南
  • 软件测试 BUG 篇