使用消息队列实现进程间通信(聊天功能)

您所在的位置:网站首页 kettle40自动创建表 使用消息队列实现进程间通信(聊天功能)

使用消息队列实现进程间通信(聊天功能)

2023-05-27 03:25| 来源: 网络整理| 查看: 265

本期分享的是使用消息队列实现进程间通信的功能,也就是我们前期分享过的聊天功能; 两个进程各自实现的功能如下: 首先,在进程中创建两个线程,一个线程负责发送消息,另一个线程负责接收消息;两个进程实现的功能其实完全一致;

以下是两个进程具体实现过程:

#include #include #include #include #include #include pthread_t tid1; pthread_t tid2; typedef struct msg { long mtype; char mtext[256]; }msg_t; //消息队列结构体 void *sendfun(void *arg) { key_t key; int msgid = -1; msg_t tmpmsg; int ret = -1; key = ftok(".", 'b'); //创建IPC对象,获取键值,第一个参数为路径,第二个参数为8bit数据即可 msgid = msgget(key, IPC_CREAT | 0664); //获取消息队列id if (-1 == msgid) { perror("fail to msgget"); return NULL; } while (1) { memset(&tmpmsg, 0, sizeof(tmpmsg)); tmpmsg.mtype = 200L; //为消息类型赋值 fgets(tmpmsg.mtext, sizeof(tmpmsg.mtext), stdin); if (!strcmp("q\n", tmpmsg.mtext)) { break; } ret = msgsnd(msgid, &tmpmsg, sizeof(tmpmsg.mtext), 0); //发送消息 if (-1 == ret) { perror("fail to msgsnd"); return NULL; } } msgctl(msgid, IPC_RMID, NULL); //删除消息队列 pthread_cancel(tid2); //结束线程 return NULL; } void *recvfun(void *arg) { key_t key; int msgid = -1; msg_t tmpmsg; int ret = -1; key = ftok(".", 'a'); msgid = msgget(key, IPC_CREAT | 0664); if (-1 == msgid) { perror("fail to msgid"); return NULL; } while (1) { memset(&tmpmsg, 0, sizeof(tmpmsg)); ret = msgrcv(msgid, &tmpmsg, sizeof(tmpmsg。), 100L, 0); //接受消息类型为100L的消息内容 if (-1 == ret) { perror("fail to msgrcv"); return NULL; } if (!strcmp("q\n", tmpmsg.mtext)) { break; } printf("recv:%s", tmpmsg.mtext); //打印接收到的消息 } msgctl(msgid, IPC_RMID, NULL); pthread_cancel(tid1); return NULL; } int main(int argc, const char *argv[]) { pthread_create(&tid1, NULL, sendfun, NULL); pthread_create(&tid2, NULL, recvfun, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); return 0; }

以上是第一个进程,第二个进程中需要注意的是两个进程进行通信,分别有接受和发送两条通道,一条是A 到 B,那么A到B的通信全部依赖于这条通道,也就是消息类型为100L的这个队列,另一条是B到A进行通信,那么消息类型为200L的消息队列; 下面是第二个进程:

#include #include #include #include #include #include pthread_t tid1; pthread_t tid2; typedef struct msg { long mtype; char mtext[256]; }msg_t; void *sendfun(void *arg) { key_t key; int msgid = -1; msg_t tmpmsg; int ret = -1; key = ftok(".", 'a'); msgid = msgget(key, IPC_CREAT | 0664); if (-1 == msgid) { perror("fail to msgget"); return NULL; } memset(&tmpmsg, 0, sizeof(tmpmsg)); tmpmsg.mtype = 100L; while (1) { fgets(tmpmsg.mtext, sizeof(tmpmsg.mtext), stdin); if (!strcmp("q\n", tmpmsg.mtext)) { break; } ret = msgsnd(msgid, &tmpmsg, sizeof(tmpmsg.mtext), 0); if (-1 == ret) { perror("fail to msgsnd"); return NULL; } } msgctl(msgid, IPC_RMID, NULL); pthread_cancel(tid2); return NULL; } void *recvfun(void *arg) { key_t key; int msgid = -1; msg_t tmpmsg; int ret = -1; key = ftok(".", 'b'); msgid = msgget(key, IPC_CREAT | 0664); if (-1 == msgid) { perror("fail to msgid"); return NULL; } while (1) { memset(&tmpmsg, 0, sizeof(tmpmsg)); ret = msgrcv(msgid, &tmpmsg, sizeof(tmpmsg), 200L, 0); if (-1 == ret) { perror("fail to msgrcv"); return NULL; } if (!strcmp("q\n", tmpmsg.mtext)) { break; } printf("recv:%s", tmpmsg.mtext); } msgctl(msgid, IPC_RMID, NULL); pthread_cancel(tid1); return NULL; } int main(int argc, const char *argv[]) { pthread_create(&tid1, NULL, sendfun, NULL); pthread_create(&tid2, NULL, recvfun, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); return 0; }

以上就是通过消息队列实现进程间通信的一个小实践,在这个项目中的收获有以下几个: (1)能够练习消息队列的函数接口; (2)更深层次的理解消息队列,它其实是内核中的一种链表,每个消息类型对应一个链表,当读取对应类型的消息时内核会自动在该链表中删除该数据,当发送该消息时,内核会自动插入该数据,这就是消息队列实现的本质; 本项目可以优化的地方:可以在主进程进行消息队列的创建,在线程中进行消息收发即可; 本次分享就到这里结束啦,欢迎小伙伴们私信留言哦!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3