多进程编程: Perl与C进程间的消息队列通信
发布时间:2020-12-16 00:18:28 所属栏目:大数据 来源:网络整理
导读:前言: perl和C语言都提供了消息队列的机制,而且这两种语言中的消息队列可以相互兼容. 当涉及到系统架构时, 可以用C语言实现核心计算模块,用Perl实现业务逻辑层, 而这两层间可以通过消息队列来实现不同语言的进程间的通信. 本文先用两个示例程序讲解Perl对消
前言:
perl和C语言都提供了消息队列的机制,而且这两种语言中的消息队列可以相互兼容. 当涉及到系统架构时,可以用C语言实现核心计算模块,用Perl实现业务逻辑层, 而这两层间可以通过消息队列来实现不同语言的进程间的通信. 本文先用两个示例程序讲解Perl对消息队列的实现。 再一个示例程序讲解Perl与C之间使用消息队列进行进程间的通信. 一. 使用IPC::SysV和IPC::Msg模块访问Unix消息队列? 例一,单个进程中实现消息队列的访问(Perl实现) File: msg_single_process.pl 1. #!/usr/bin/perl 2. use strict; 3. use warnings; 4. use IPC::SysV qw(IPC_PRIVATE S_IRWXU S_IRWXG S_IRWXO IPC_CREAT IPC_NOWAIT); 5. use IPC::Msg; 6. my($key,$msg,$msgid,$msgtype,$buf); 7. $key = IPC::SysV::ftok(".",'1'); 8. $msg = new IPC::Msg($key,0666 | IPC_CREAT) or die "create message queue: $!"; 9. $msgtype = 1; 10.$msgid = $msg->id(); 11.print "MSG_ID: ","n"; 12.$msg->snd($msgtype,"test",IPC_NOWAIT) or die "send message failed: $!"; 13.$msg->rcv($buf,1024) or die "receive message failed: $!"; 14.print "BUFFER: ",$buf,51)">15.$msg->remove(); 代码解释: 4.使用IPC::SysV模块,Arial; line-height:26px; font-size:14px">? qw(IPC_PRIVATE S_IRWXU S_IRWXG S_IRWXO IPC_CREAT IPC_NOWAIT) ? 等同于("IPC_PRIVATE S_IRWXU S_IRWXG S_IRWXO IPC_CREAT IPC_NOWAIT"),Arial; line-height:26px; font-size:14px">? 表示本程序将从该模块引入若干符号,Arial; line-height:26px; font-size:14px">? 在后续的代码里面需要要指定模块名就可以使用这些符号; 5.使用IPC::Msg模块(消息队列); 6.定义私有变量; 7.用ftok通过文件名获得一个key_t值,这里使用是当前目录. ? 类似C语言中的ftok函数,这个文件必须实际存在; 8.获得Msg对象。类似msgget函数; 9.指定消息类型; 10.获得消息队列的标识符; 12.发送消息。类似msgsnd函数; 13.接收消息。类似msgrcv函数; 15.删除消息队列; 更多的信息,可以参考IPC::Msg模块定义: http://search.cpan.org/~mhx/IPC-SysV-2.03/lib/IPC/Msg.pm 例二.在两个进程间使用消息队列进行通信(Perl实现) File: msg_snd.pl #!/usr/bin/perl use strict; use warnings; use IPC::SysV qw(IPC_PRIVATE S_IRWXU S_IRWXG S_IRWXO IPC_CREAT IPC_NOWAIT); use IPC::Msg; my($key,51)">$key = IPC::SysV::ftok(".",51)">$msg = new IPC::Msg($key,51)">$msgtype = 1; $msgid = $msg->id(); print "MSG_ID: ",51)">my $pal; foreach $pal('Tom','Dick','Harry','Pete','Hank') { ? $msg->snd($msgtype,"Hi,$pal",51)">? print "BUFFER: ",$pal,51)">} ?? # end $msg->snd($msgtype,"end",51)">print "BUFFER: endn"; File: msg_rcv.pl my $running = 1; while ($running) ? $msg->rcv($buf,51)">? if($buf eq "end") ? { ? ? $running = 0; ? } $msg->remove(); 二. C与Perl进程间的消息队列通信 接收端使用Perl实现 msg_rcv.pl #$key = IPC::SysV::ftok(".",51)">$key = 1234; ? my $pos = index($buf,0); ? print "POS: ",$pos,51)">? if ($pos != -1) 发送端采用C代码实现 msg_snd.c #include <stdio.h> #include <string.h> #include <errno.h> #include <unistd.h> #include <sys/msg.h> #define MAX_TEXT 512 ? long int my_msg_type; ? char some_text[MAX_TEXT]; }; int main() ? int index; ? struct my_msg_st some_data; ? int msgid; ? msgid = msgget((key_t)1234,0666 | IPC_CREAT); ? if (msgid == -1) ? ? fprintf(stderr,"msgget failed with error: %dn",errno); ? ? exit(EXIT_FAILURE); ? for (index = 0; index < 10; index++) ? ? memset(some_data.some_text,MAX_TEXT); ? ? some_data.my_msg_type = 1; ? ? snprintf(some_data.some_text,MAX_TEXT,"%s~%d","index",index); ? ? if (msgsnd(msgid,(void *)&some_data,0) == -1) ? ? { ? ? ? fprintf(stderr,"msgsnd failedn"); ? ? ? exit(EXIT_FAILURE); ? ? } ? /* ending */ ? memset(some_data.some_text,51)">? some_data.my_msg_type = 1; ? snprintf(some_data.some_text,"%s","end"); ? if (msgsnd(msgid,51)">? exit(EXIT_SUCCESS); } 编译与运行: $gcc -g -Wall -o msg_snd msg_snd_c.c?$./msg_rcv.pl & $./msg_snd 输出: MSG_ID: 393219 BUFFER: index~0 BUFFER: index~1 BUFFER: index~2 BUFFER: index~3 BUFFER: index~4 BUFFER: index~5 BUFFER: index~6 BUFFER: index~7 BUFFER: index~8 BUFFER: index~9 BUFFER: end (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |