下面代码运行后为啥子进程打印一次后没反应了#include <stdio.h>

下面代码运行后为啥子进程打印一次后没反应了

img

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <wait.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgid;
// 定义一个消息结构体
struct message {
    long mtype;
    char mtext[1024];
};
// 信号处理器
void handler(int sig) {
    if (sig == SIGUSR1) {
        // 接收到 SIGUSR1 信号,执行相应操作
        if (fork() == 0) {
            // 子进程循环接收消息并处理
            while (1) {
                // 从消息队列中接收消息
                struct message msg;
                msgrcv(msgid, &msg, sizeof(msg), 1, 0);

                // 如果接收到 "bye" 消息,退出循环
                if (strcmp(msg.mtext, "bye") == 0) {
                    break;
                }

                // 将接收到的消息写入终端
                write(1, msg.mtext, strlen(msg.mtext));

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

            // 子进程结束
            exit(0);
        }
    }
}
int main() {
    // 创建消息队列
    msgid = msgget(IPC_PRIVATE, 0666 | IPC_CREAT);

    // 安装信号处理器
    signal(SIGUSR1, handler);

    // 父进程循环发送消息
    while (1) {
        // 向消息队列发送消息
        struct message msg;
        msg.mtype = 1;
        printf("Enter a message (\"bye\" to exit): ");
        scanf("%s", msg.mtext);
        msgsnd(msgid, &msg, sizeof(msg), 0);

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

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

    // 删除消息队列
    msgctl(msgid, IPC_RMID, NULL);
    return 0;
}

望采纳


上面代码实现了父进程和子进程通过消息队列进行通信,父进程接收用户输入的消息并发送给子进程,子进程接收消息并写入终端。

当父进程接收到 "bye" 消息时,它会向子进程发送一个信号,子进程接收到该信号后会退出循环,然后结束。这就是为什么程序在打印一次后没有反应的原因。

如果您想让程序继续运行,可以在主循环中添加一个特殊的消息,例如 "continue",然后在子进程中检查接收到的消息是否为 "continue"。如果是,就不退出循环,而是继续处理消息。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <wait.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgid;

// 定义一个消息结构体
struct message {
    long mtype;
    char mtext[1024];
};

// 信号处理器
void handler(int sig) {
    if (sig == SIGUSR1) {
        // 接收到 SIGUSR1 信号,执行相应操作
        if (fork() == 0) {
            // 子进程循环接收消息并处理
            while (1) {
                // 从消息队列中接收消息
                struct message msg;
                msgrcv(msgid, &msg, sizeof(msg), 1, 0);

                // 如果接收到 "bye" 消息,退出循环
                if (strcmp(msg.mtext, "bye") == 0) {
                    break;
                }

                // 如果接收到 "continue" 消息,不退出循环
                if (strcmp(msg.mtext, "continue") == 0) {
                    continue;
                }

                // 将接收到的消息写入终端
                write(1, msg.mtext, strlen(msg.mtext));

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

            // 子进程结束
            exit(0);
        }
    }
}

int main() {
    // 创建消息队列
    msgid = msgget(IPC_PRIVATE, 0666 | IPC_CREAT);

    // 安装信号处理器
    signal(SIGUSR1, handler);

    // 父进程循环发送消息
    while (1) {
        // 向消息队列发送消息
        struct message msg;
        msg.mtype = 1;
        printf("Enter a message (\"bye\" to exit, \"continue\" to continue): ");
        scanf("%s", msg.mtext);
        msgsnd(msgid, &msg, sizeof(msg), 0);

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

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

    // 删除消息队列
    msgctl(msgid, IPC_RMID, NULL);
    return 0;
}