linux开发 c语言多进程通讯demo(队列msg,信号,共享内存)
注意,初始化必须在一个线程里面,不然可能出错
msg代码 接受者后台运行 发送者前端输入
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <sys/msg.h> struct my_msg_st { long int my_msg_type; // 这个是必须的 并且使用时,赋值需要>0 char some_text[BUFSIZ]; }; int main() { int running = 1; int msgid; struct my_msg_st some_data; long int msg_to_receive = 0; msgid = msgget((key_t)1234, 0666 | IPC_CREAT); if (msgid == -1) { fprintf(stderr, "msgget failed with error: %d\n", errno); exit(EXIT_FAILURE); } while(running) { if (msgrcv(msgid, (void *)&some_data, BUFSIZ, msg_to_receive, 0) == -1) { fprintf(stderr, "msgrcv failed with error: %d\n", errno); exit(EXIT_FAILURE); } printf("You wrote: %s", some_data.some_text); if (strncmp(some_data.some_text, "end", 3) == 0) { running = 0; } } if (msgctl(msgid, IPC_RMID, 0) == -1) { fprintf(stderr, "msgctl(IPC_RMID) failed\n"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }
发送者
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <sys/msg.h> #define MAX_TEXT 512 struct my_msg_st { long int my_msg_type; // 这个是必须的 并且使用时,赋值需要>0 char some_text[MAX_TEXT]; }; int main() { int running = 1; struct my_msg_st some_data; int msgid; char buffer[BUFSIZ]; msgid = msgget((key_t)1234, 0666 | IPC_CREAT); if (msgid == -1) { fprintf(stderr, "msgget failed with error: %d\n", errno); exit(EXIT_FAILURE); } while(running) { printf("Enter some text: "); fgets(buffer, BUFSIZ, stdin); some_data.my_msg_type = 1; strcpy(some_data.some_text, buffer); if (msgsnd(msgid, (void *)&some_data, MAX_TEXT, 0) == -1) { fprintf(stderr, "msgsnd failed\n"); exit(EXIT_FAILURE); } if (strncmp(buffer, "end", 3) == 0) { running = 0; } } exit(EXIT_SUCCESS); }
信号量,和共享内存配合使用 sem_server 产生消息,写入共享内存,发送信号提醒客户端接收
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/mman.h> #include <sys/stat.h> #include <semaphore.h> #include <unistd.h> #include <string.h> #define SHM_NAME "/my_shm" #define SEM_NAME "/my_sem" int main() { int shm_fd; char *shm_ptr; sem_t *sem; // 创建共享内存 shm_fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, 0666); if (shm_fd == -1) { perror("shm_open"); exit(EXIT_FAILURE); } // 设置共享内存大小 if (ftruncate(shm_fd, sizeof(char) * 10) == -1) { perror("ftruncate"); exit(EXIT_FAILURE); } // 映射共享内存到进程地址空间 shm_ptr = mmap(NULL, sizeof(char) * 10, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); if (shm_ptr == MAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); } // 初始化命名信号量 sem = sem_open(SEM_NAME, O_CREAT | O_EXCL, 0666, 0); if (sem == SEM_FAILED) { perror("sem_open"); sem_unlink(SEM_NAME); exit(EXIT_FAILURE); } while (1) { // 模拟写入数据到共享内存(通常是由另一个进程来做) strncpy(shm_ptr, "Hello", 5); printf("server write:%s\n",shm_ptr); // 释放信号量,允许客户端访问共享内存 if (sem_post(sem) == -1) { perror("sem_post"); exit(EXIT_FAILURE); } printf("server wake up sem\n"); // ... 这里可以等待客户端完成或者其他逻辑 ... sleep(1); } printf("server release\n"); // 清理 sem_close(sem); sem_unlink(SEM_NAME); munmap(shm_ptr, sizeof(char) * 10); shm_unlink(SHM_NAME); close(shm_fd); return 0; }
客户端代码
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/mman.h> #include <semaphore.h> #include <unistd.h> #include <string.h> #define SHM_NAME "/my_shm" #define SEM_NAME "/my_sem" int main() { int shm_fd; char *shm_ptr; sem_t *sem; // 打开命名信号量 sem = sem_open(SEM_NAME, 0); if (sem == SEM_FAILED) { perror("sem_open"); exit(EXIT_FAILURE); } // 打开共享内存 shm_fd = shm_open(SHM_NAME, O_RDONLY, 0666); if (shm_fd == -1) { perror("shm_open"); exit(EXIT_FAILURE); } // 映射共享内存到进程地址空间 shm_ptr = mmap(NULL, 10, PROT_READ, MAP_SHARED, shm_fd, 0); if (shm_ptr == MAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); } while (1) { // 等待信号量变为非零值 if (sem_wait(sem) == -1) { perror("sem_wait"); exit(EXIT_FAILURE); } // 读取并显示共享内存内容 printf("Content from shared memory: %s\n", shm_ptr); } // 清理 munmap(shm_ptr, 10); close(shm_fd); sem_close(sem); return 0; }
//
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构