c语言+pipe实现父子进程通信(双向通信+发送多条信息+发送结构体)

chatgpt写的,我调了一下,觉得挺好,发个博客记录一下
测试环境是ubuntu
感觉关键就是write的时候要sleep,然后写的时候要while读。总觉得怪怪的,干脆一次读写完算了。

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

#define BUFFER_SIZE 256

int main() {
    int pipe_parent_child[2];  // 父进程到子进程的管道
    int pipe_child_parent[2];  // 子进程到父进程的管道
    pid_t pid;
    char buffer[BUFFER_SIZE];

    // 创建父子进程间的管道
    if (pipe(pipe_parent_child) == -1 || pipe(pipe_child_parent) == -1) {
        perror("Pipe creation failed");
        exit(EXIT_FAILURE);
    }

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

    if (pid == -1) {
        perror("Fork failed");
        exit(EXIT_FAILURE);
    }

    if (pid > 0) { // Parent process
        close(pipe_parent_child[0]); // 父进程关闭从父进程到子进程的读端
        close(pipe_child_parent[1]); // 父进程关闭从子进程到父进程的写端

        // 父进程向子进程发送消息
        const char* messages_to_child[] = {"Hello, child!", "How are you?", "Do you want to play?"};
        for (int i = 0; i < sizeof(messages_to_child) / sizeof(messages_to_child[0]); ++i) {
            write(pipe_parent_child[1], messages_to_child[i], strlen(messages_to_child[i]) + 1);
            printf("Parent sent: %s\n", messages_to_child[i]);
            sleep(1); // 延迟一秒,模拟发送多条消息的间隔
        }

        close(pipe_parent_child[1]); // 关闭父进程到子进程的写端,表示发送完毕

        // 父进程从子进程接收消息
        while (read(pipe_child_parent[0], buffer, BUFFER_SIZE) > 0) {
            printf("Parent received: %s\n", buffer);
        }

        close(pipe_child_parent[0]); // 关闭从子进程到父进程的读端
    } else { // Child process
        close(pipe_parent_child[1]); // 子进程关闭从父进程到子进程的写端
        close(pipe_child_parent[0]); // 子进程关闭从子进程到父进程的读端

        // 子进程从父进程接收消息
        while (read(pipe_parent_child[0], buffer, BUFFER_SIZE) > 0) {
            printf("Child received: %s\n", buffer);
        }
        close(pipe_parent_child[0]); // 关闭从父进程到子进程的读端
        // 子进程向父进程发送消息
        const char* messages_to_parent[] = {"Hi, parent!", "I'm fine, thanks.", "Sure!"};
        for (int i = 0; i < sizeof(messages_to_parent) / sizeof(messages_to_parent[0]); ++i) {
            write(pipe_child_parent[1], messages_to_parent[i], strlen(messages_to_parent[i]) + 1);
            printf("Child sent: %s\n", messages_to_parent[i]);
            sleep(1); // 延迟一秒,模拟发送多条消息的间隔
        }
        close(pipe_child_parent[1]); // 关闭从子进程到父进程的写端,表示发送完毕
    }

    return 0;
}

下面再分享一个发结构体数据的

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

#define MAX_BUFFER_SIZE 1024

// 结构体定义
typedef struct {
    char *filename;
} Input;

typedef struct  {
    int status;
    char log[100];
    int spendTime;
    int spendMemory;
}Output;

void child_process(pid_t pid,int main2child[2],int child2main[2]){
    close(child2main[0]);
    close(main2child[1]);
    char buffer[MAX_BUFFER_SIZE];
    Input recv_data;
    // 子进程
    // 从管道读取数据
    read(main2child[0], &recv_data, sizeof(Input));
    printf("拿到%s",recv_data.filename);
    close(main2child[0]); // 关闭读端
    sleep(2);
    printf("子进程执行完操作\n");
    Output send_data={1,"loglog",43000,12344};
  
    write(child2main[1], &send_data, sizeof(Output));
    close(child2main[1]); // 关闭写端
}

Output main_process(pid_t pid,int main2child[2],int child2main[2],int max_time){
    close(main2child[0]);
    close(child2main[1]);
    char buffer[MAX_BUFFER_SIZE];
     Input send_data={"code.c"};
    // 父进程
    write(main2child[1], &send_data, sizeof(Input));
    close(main2child[1]); // 关闭写端
    // wait(NULL); // 等待子进程结束
    int remaining_time = max_time;
    int status;
    // close(pipefd[0]);
    while(1){
        sleep(1);
        remaining_time--;
        if (waitpid(pid, &status, WNOHANG) == 0) {
            printf("子进程还在运行\n");
            if(remaining_time < 0){
                kill(pid, SIGKILL);
                Output recv_data={1,"运行超时",0,0};
                close(child2main[0]); // 关闭读端
                return recv_data;
            }
        } else {
            printf("子进程结束\n");
            Output recv_data;
            read(child2main[0], &recv_data, sizeof(Output));
            close(child2main[0]); // 关闭读端
            return recv_data;
        }
    }
}

int main() {
    pid_t pid;
    // 创建管道
    int main2child[2],child2main[2];
    if (pipe(main2child) == -1 || pipe(child2main) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }
    // 创建子进程
    pid = fork();
    if (pid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    } else {
        if (pid == 0) {
            child_process(pid,main2child,child2main);
            exit(EXIT_SUCCESS);
        } else {
            int max_time = 5;
            Output run_res = main_process(pid,main2child,child2main,max_time);
            printf("%d %s %d %d\n",run_res.status,run_res.log,run_res.spendTime,run_res.spendMemory);
            exit(EXIT_SUCCESS);
        }
    }
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值