进程间通信方式有以下几种:

  1. 管道(Pipe):管道是一种半双工的通信方式,只能在具有亲缘关系的进程之间使用,一般用于父子进程之间的通信。
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    int fd[2];
    pid_t pid;
    char buf[1024];
    if (pipe(fd) < 0) {
        perror("pipe error");
        exit(1);
    }
    if ((pid = fork()) < 0) {
        perror("fork error");
        exit(1);
    } else if (pid > 0) { // 父进程
        close(fd[0]); // 关闭读端
        write(fd[1], "hello world\n", 12);
    } else { // 子进程
        close(fd[1]); // 关闭写端
        read(fd[0], buf, 1024);
        printf("%s", buf);
    }
    return 0;
}
  1. 命名管道(Named Pipe):命名管道是一种半双工的通信方式,可以在不具有亲缘关系的进程之间使用,一般用于客户端与服务器之间的通信。
// 服务端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
    int fd;
    char buf[1024];
    if (mkfifo("fifo", 0666) < 0) { // 创建命名管道
        perror("mkfifo error");
        exit(1);
    }
    if ((fd = open("fifo", O_RDONLY)) < 0) { // 打开命名管道
        perror("open error");
        exit(1);
    }
    read(fd, buf, 1024);
    printf("%s", buf);
    close(fd);
    return 0;
}

// 客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
    int fd;
    if ((fd = open("fifo", O_WRONLY)) < 0) { // 打开命名管道
        perror("open error");
        exit(1);
    }
    write(fd, "hello world\n", 12);
    close(fd);
    return 0;
}
  1. 消息队列(Message Queue):消息队列是一种异步的通信方式,可以在不具有亲缘关系的进程之间使用。
// 发送方
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>

struct msgbuf {
    long mtype;
    char mtext[1024];
};

int main()
{
    int msqid;
    struct msgbuf buf;
    key_t key;
    if ((key = ftok(".", 'a')) < 0) { // 创建key
        perror("ftok error");
        exit(1);
    }
    if ((msqid = msgget(key, IPC_CREAT | 0666)) < 0) { // 创建消息队列
        perror("msgget error");
        exit(1);
    }
    buf.mtype = 1; // 消息类型
    strcpy(buf.mtext, "hello world");
    if (msgsnd(msqid, &buf, strlen(buf.mtext), 0) < 0) { // 发送消息
        perror("msgsnd error");
        exit(1);
    }
    return 0;
}

// 接收方
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>

struct msgbuf {
    long mtype;
    char mtext[1024];
};

int main()
{
    int msqid;
    struct msgbuf buf;
    key_t key;
    if ((key = ftok(".", 'a')) < 0) { // 创建key
        perror("ftok error");
        exit(1);
    }
    if ((msqid = msgget(key, IPC_CREAT | 0666)) < 0) { // 创建消息队列
        perror("msgget error");
        exit(1);
    }
    if (msgrcv(msqid, &buf, 1024, 1, 0) < 0) { // 接收消息
        perror("msgrcv error");
        exit(1);
    }
    printf("%s", buf.mtext);
    if (msgctl(msqid, IPC_RMID, NULL) < 0) { // 删除消息队列
        perror("msgctl error");
        exit(1);
    }
    return 0;
}
  1. 共享内存(Shared Memory):共享内存是一种高效的通信方式,可以实现多个进程之间的数据共享。
// 写进程
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>

struct shared_mem {
    int flag;
    char buf[1024];
};

int main()
{
    int shmid;
    struct shared_mem *shmptr;
    key_t key;
    if ((key = ftok(".", 'a')) < 0) { // 创建key
        perror("ftok error");
        exit(1);
    }
    if ((shmid = shmget(key, sizeof(struct shared_mem), IPC_CREAT | 0666)) < 0) { // 创建共享内存
        perror("shmget error");
        exit(1);
    }
    if ((shmptr = (struct shared_mem *)shmat(shmid, NULL, 0)) == (void *)-1) { // 将共享内存映射到进程的地址空间中
        perror("shmat error");
        exit(1);
    }
    while (1) {
        if (shmptr->flag == 0) {
            fgets(shmptr->buf, sizeof(shmptr->buf), stdin);
            shmptr->flag = 1;
        }
    }
    if (shmdt(shmptr) < 0) { // 解除共享内存映射
        perror("shmdt error");
        exit(1);
    }
    return 0;
}

// 读进程
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>

struct shared_mem {
    int flag;
    char buf[1024];
};

int main()
{
    int shmid;
    struct shared_mem *shmptr;
    key_t key;
    if ((key = ftok(".", 'a')) < 0) { // 创建key
        perror("ftok error");
        exit(1);
    }
    if ((shmid = shmget(key, sizeof(struct shared_mem), IPC_CREAT | 0666)) < 0) { // 创建共享内存
        perror("shmget error");
        exit(1);
    }
    if ((shmptr = (struct shared_mem *)shmat(shmid, NULL, 0)) == (void *)-1) { // 将共享内存映射到进程的地址空间中
        perror("shmat error");
        exit(1);
    }
    while (1) {
        if (shmptr->flag == 1) {
            printf("%s", shmptr->buf);
            shmptr->flag = 0;
        }
    }
    if (shmdt(shmptr) < 0) { // 解除共享内存映射
        perror("shmdt error");
        exit(1);
    }
    return 0;
}
  1. 信号量(Semaphore):信号量是一种用于进程间同步和互斥的机制。
// 写进程
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>

int main()
{
    int semid;
    struct sembuf semops;
    key_t key;
    if ((key = ftok(".", 'a')) < 0) { // 创建key
        perror("ftok error");
        exit(1);
    }
    if ((semid = semget(key, 1, IPC_CREAT | 0666)) < 0) { // 创建信号量
        perror("semget error");
        exit(1);
    }
    semops.sem_num = 0;
    semops.sem_op = 1; // 信号量加1
    semops.sem_flg = SEM_UNDO;
    while (1) {
        semop(semid, &semops, 1); // 发送信号量
        sleep(1);
    }
    return 0;
}

// 读进程
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>

int main()
{
    int semid;
    struct sembuf semops;
    key_t key;
    if ((key = ftok(".", 'a')) < 0) { // 创建key
        perror("ftok error");
        exit(1);
    }
    if ((semid = semget(key, 1, IPC_CREAT | 0666)) < 0) { // 创建信号量
        perror("semget error");
        exit(1);
    }
    semops.sem_num = 0;
    semops.sem_op = -1; // 信号量减1
    semops.sem_flg = SEM_UNDO;
    while (1) {
        semop(semid, &semops, 1); // 接收信号量
        printf("hello world\n");
    }
    return 0;
}
进程间通信方式有哪些?各举例实现一个demo

原文地址: https://www.cveoy.top/t/topic/bpbb 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录