当前位置:职场发展 > 讲解Unix消息队列的应用

讲解Unix消息队列的应用

  • 发布:2023-09-29 22:29

今天我们来学习Unix消息队列的知识。首先我们举一个Unix消息队列在C/S模式下的应用示例。 C/S的一个重要特征是非互惠性。多个客户端同时向服务器发出不同的请求。服务器接收并处理客户端的请求后,将结果返回给相应的客户端。这里,我们使用两个Unix消息队列、一个服务进程和几个客户端进程来模拟客户端/服务应用程序。 每个客户端进程将请求信息写入队列1(键值0x16),消息类型设置为10;服务进程从队列1中读取类型10的消息进行处理,并将处理结果放入Unix消息队列2中(键值为0x17),将类型设置为原来的客户端进程号,这样每个客户端进程都可以读取自己的消息根据消息类型(即进程号)从队列 2 中得出结果。 具体操作,首先启动服务进程(server.c),创建两个key值分别为十六进制16和17的Unix消息队列;然后启动几个客户端进程(client.c)并输入任意字符串。 ,此时服务进程显示客户端进程号和原始字符串,客户端进程回显处理后的字符串和消息类型(自己的进程号),第一个字符改为“_”。如果输入字符“q”,则原有的Unix消息队列将被删除并同时退出。附源程序清单。该程序已在UNIX3.2和4.2环境下编译和调试。 这只是机器内部进程通信的实现。要实现网络上进程之间的通信,也可以借助UNIX互联网系统的套接字来实现。 源程序列表如下: ​服务进程:(server.c) #include #include #include #include #define KEY16 (key_t)16 #define KEY17 (key_t)17 #include (c type.h) int i,msgid1,msgid2,val; char *s struct{ 长 mtype;短型;字符多行文字[40]; }缓冲区; main() { cr_q(); /* 创建消息队列 */ /* 读取消息队列1,消息队列类型为10,等待客户端请求 */ while (msgrcv(msgid1,&buf,42,(long)10, ~ IPC_NOWAIT)>=0) { printf("\n 来自客户端的文本是:[%s]", buf.mtext); printf("客户端pid是<%d>\n",buf.stype); process();/* 将处理结果写入消息队列2*/ } } cr_q() { msgid1=msgget(KEY16 ,IPC_CREAT|0666); if (msgid1<0) {perror("key16 msgget 失败");exit(1);} msgid2=msgget(KEY17,IPC_CREAT|0666); if (msgid2<0) {perror("key17 msgget failed");exit(1);} } process() { bufbuf.mtype=buf.stype;/* 原始客户端进程号 */ buf.mtext[0]= '_'; if(msgsnd(msgid2,&buf ,42,IPC_NOWAIT)<0) {perror("key17 msgsnd 失败");exit(1);} }客户端进程:(client.c) #include #include #include #include Define KEY16 (key_t)16 Define KEY17 (key_t)17 include int msgid1,msgid2;结构体{长mtype;短型;字符多行文字[40]; }缓冲区;字符s[41]; int clean() main() { get_q();/* 取消队列标识符 */ while (1) { printf (" \n @input mtext:");/* 输入字符串 */ scanf("%s",s ); if ((strcmp(s,"q")==0)) 中断; strcpy(buf.mtext, s); buf.mtype=10; /* 设置消息类型为10*/ buf.stype=getpid();/* 客户端进程号 */ /* 写入消息队列1,向服务进程发出请求 */ if (msgsnd (msgid1,&buf,40 , ~ IPC_NOWAIT)<0) {perror("key16 msgsnd failed");exit(1);} /* 读取消息队列2,类型为自身进程号,接收处理结果 */ if (msgrcv (msgid2,&buf,42 ,getpid(), ~ IPC_NOWAIT)<0) {perror("key17 msgrcv failed");exit(1);} printf("\n 服务器的答案是:[%s]", buf.mtext); printf("mtype 为:[%d]",buf.mtype); } clean();/* 删除消息队列 */ } clean() { if(msgct1(msgid1,IPC_RMID,(struct msgid *)NULL)<0) {perror("key16 msgct1 失败ed");exit(1);} if(msgct1(msgid2,IPC_RMID,(struct msgid*)NULL<0) {perror("key17 msgct1 失败");exit(1);} printf("消息队列已删除\ n"); exit(0); } get_q() { msgid1=msgget(KEY16,0); if (msgid1<0) {perror("key16 msgget 失败");exit(1);} msgid2=msgget(KEY17 ,0);if (msgid2<0) {perror("key17 msgget failed");exit(1);} } 关于Unix消息队列的应用,今天就讲解到这里了,希望大家能够好好学习。我们将带来更多Unix消息队列应用的知识。 【编辑精选】 Linux多线程同步消息队列 Unix消息队列知识详解 www.sychzs.cn消息队列相关内容详细介绍 WCF消息队列系列简介 解释WCF消息队列的具体问题

相关文章