为了账号安全,请及时绑定邮箱和手机立即绑定

作业社区

探索学习新天地,共享知识资源!

0 提交作业
0 布置作业
0 满分作业
得分 100
学习任务

沫颖 的学生作业:

代码 // 封装函数版本 #include #include #include #include #include #include #include #include #include // 定义用于ftok的路径和项目ID #define PATHNAME "." #define PROID 24 // 消息类型 #define MSG_TYPE_A 100 #define MSG_TYPE_B 200 // 消息内容最大长度 #define MSG_SIZE 128 // 消息结构体 struct msgbuf { long mtype; char mtext[MSG_SIZE]; }; // 信号处理函数 void sigterm_a_handler(int signum) { printf("Received SIGTERM, Process A exiting...\n"); exit(EXIT_SUCCESS); } void sigterm_b_handler(int signum) { printf("Received SIGTERM, Process B exiting...\n"); exit(EXIT_SUCCESS); } // 注册信号处理函数 (sigtype 1: A, 2: B) void register_signal_handler(const int sigtype) { __sighandler_t sig_ret; sig_ret = sigtype == 1 ? signal(SIGTERM, sigterm_a_handler) : signal(SIGTERM, sigterm_b_handler); if (sig_ret == SIG_ERR) { perror("[ERROR] signal():"); exit(EXIT_FAILURE); } } // 接收消息 struct msgbuf receive_message(int msgid, long msgtype) { // 接收的消息结构体 struct msgbuf rcv_msg; ssize_t rbytes; // 从消息队列中接收消息 rbytes = msgrcv(msgid, (void *)&rcv_msg, MSG_SIZE, msgtype, 0); if (rbytes == -1) { perror("[ERROR] msgrcv() :"); } return rcv_msg; } // 发送消息 void send_messages(int msgid, const char *input) { struct msgbuf send_msg_a, send_msg_b; send_msg_a.mtype = MSG_TYPE_A; strcpy(send_msg_a.mtext, input); send_msg_b.mtype = MSG_TYPE_B; strcpy(send_msg_b.mtext, input); int ret_a = msgsnd(msgid, (void *)&send_msg_a, strlen(send_msg_a.mtext) + 1, 0); int ret_b = msgsnd(msgid, (void *)&send_msg_b, strlen(send_msg_b.mtext) + 1, 0); if (ret_a == -1 || ret_b == -1) { perror("[ERROR] msgsnd():"); exit(EXIT_FAILURE); } } int main(int argc, char const *argv[]) { key_t key; int msgid; // 创建消息队列的key key = ftok(PATHNAME, PROID); if (key == -1) { perror("[ERROR] ftok() :"); exit(EXIT_FAILURE); } // 创建消息队列 msgid = msgget(key, IPC_CREAT | 0666); pid_t cpid; // 创建进程 cpid = fork(); if (cpid == -1) { perror("[ERROR] fork() A:"); exit(EXIT_FAILURE); } else if (cpid == 0) { // 注册自定义信号处理函数 register_signal_handler(1); // 接收的消息结构体 struct msgbuf rcv_msg_a; // 子进程A,负责接收消息类型为 100 的消息 while (1) { // 从消息队列中接收消息 rcv_msg_a = receive_message(msgid, MSG_TYPE_A); printf("rcv_msg_a.mtype = %ld\n", rcv_msg_a.mtype); printf("rcv_msg_a.mtext = %s\n", rcv_msg_a.mtext); } } else if (cpid > 0) { pid_t cpidB; // 创建进程 cpidB = fork(); if (cpidB == -1) { perror("[ERROR] fork() B:"); exit(EXIT_FAILURE); } else if (cpidB == 0) { // 注册自定义信号处理函数 register_signal_handler(2); // 接收的消息结构体 struct msgbuf rcv_msg_b; // 子进程A,负责接收消息类型为 100 的消息 while (1) { // 从消息队列中接收消息 rcv_msg_b = receive_message(msgid, MSG_TYPE_B); printf("rcv_msg_b.mtype = %ld\n", rcv_msg_b.mtype); printf("rcv_msg_b.mtext = %s\n", rcv_msg_b.mtext); } } else if (cpidB > 0) { sleep(1); // 循环向消息队列中发送消息 while (1) { // 获取用户输入,作为消息,发送至消息队列 char input[MSG_SIZE]; printf("Please input a message: \n"); if (fgets(input, MSG_SIZE, stdin) == NULL) { perror("[ERROR] fgets() :"); exit(EXIT_FAILURE); } // 处理输入,去除换行符 size_t len = strlen(input); if (len > 0 && input[len - 1] == '\n') { input[len - 1] = '\0'; } // 当输入quit时退出 if (strcmp(input, "quit") == 0) { // 结束子进程 kill(cpid, SIGTERM); kill(cpidB, SIGTERM); waitpid(cpid, NULL, 0); waitpid(cpidB, NULL, 0); // 删除消息队列 if (msgctl(msgid, IPC_RMID, NULL) == -1) { perror("[ERROR] msgctl() :"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } // 发送消息 send_messages(msgid, input); } } } return 0; } 效果 【图片】

微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号