首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Perl 與 C 進程間通訊:System V 消息隊列完整實戰指南

     編輯:關於C語言

架構優勢

核心計算模組用 C 實現 (效能),業務邏輯層用 Perl 實現 (開發效率),兩者透過 System V 消息隊列 (IPC) 通訊,實現異語言進程協作。

一、Perl 端消息隊列操作 (IPC::SysV + IPC::Msg)

單進程測試


#!/usr/bin/perl
use strict; use warnings;
use IPC::SysV qw(IPC_PRIVATE S_IRWXU IPC_CREAT IPC_NOWAIT);
use IPC::Msg;

my $key = IPC::SysV::ftok(".", '1');  # 需存在的檔案產生 key
my $msg = IPC::Msg->new($key, 0666 | IPC_CREAT) or die "create: $!";
my $msgid = $msg->id;
print "MSG_ID: $msgid\n";

$msg->snd(1, "test", IPC_NOWAIT) or die "send: $!";
$msg->rcv(my $buf, 1024) or die "recv: $!";
print "BUFFER: $buf\n";

$msg->remove();  # 刪除隊列

雙進程通訊:發送端 msg_snd.pl


my $msg = IPC::Msg->new($key, 0666 | IPC_CREAT);
my $msgtype = 1;
foreach my $pal (qw(Tom Dick Harry Pete Hank)) {
    $msg->snd($msgtype, "Hi, $pal", IPC_NOWAIT) or die "send: $!";
    print "SENT: $pal\n";
}
$msg->snd($msgtype, "end", IPC_NOWAIT);  # 結束信號

接收端 msg_rcv.pl


my $msg = IPC::Msg->new($key, 0666 | IPC_CREAT);
my $running = 1;
while ($running) {
    $msg->rcv(my $buf, 1024) or die "recv: $!";
    print "RECV: $buf\n";
    $running = 0 if $buf eq "end";
}
$msg->remove();

二、C 與 Perl 混合通訊

關鍵:雙方使用相同的 key (此處固定為 1234),消息結構體定義一致。

Perl 接收端 (固定 key)


my $key = 1234;  # 不再用 ftok
my $msg = IPC::Msg->new($key, 0666 | IPC_CREAT);
# ... 同前 ...

C 發送端 msg_snd.c


#include 
#include 
#include 
#include 
#include 

#define MAX_TEXT 512

struct my_msg_st {
    long int my_msg_type;  // 必須為 long,且 > 0
    char some_text[MAX_TEXT];
};

int main() {
    int msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
    if (msgid == -1) { perror("msgget"); exit(1); }

    struct my_msg_st data;
    for (int i = 0; i < 10; i++) {
        data.my_msg_type = 1;
        snprintf(data.some_text, MAX_TEXT, "index~%d", i);
        if (msgsnd(msgid, &data, MAX_TEXT, 0) == -1) { perror("msgsnd"); exit(1); }
    }
    // 發送結束信號
    data.my_msg_type = 1;
    strcpy(data.some_text, "end");
    msgsnd(msgid, &data, MAX_TEXT, 0);
    return 0;
}

編譯與執行


gcc -o msg_snd msg_snd.c
./msg_rcv.pl &   # 後台運行接收端
./msg_snd        # 運行發送端

輸出示例

MSG_ID: 393219
BUFFER: index~0
BUFFER: index~1
...
BUFFER: index~9
BUFFER: end

關鍵注意事項

擴展建議

  • 使用 IPC_NOWAIT 非阻塞模式配合 select/poll 實現多隊列多工
  • 定義結構體版本號,支援協定演進
  • 考慮改用 POSIX 消息隊列 (mq_open/mq_send) 獲得更佳介面與通知機制
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
項目要求
消息類型long 且 > 0 (Perl/C 一致)
資料長度msgsnd 第三參數為資料長度 (不含 long type),雙方約定一致
key 產生C 用 ftok 或固定整數;Perl 用 IPC::SysV::ftok 或相同整數
權限0666 | IPC_CREAT 雙方一致
隊列清理接收端最後呼叫 $msg->remove() 或 C 端 msgctl(msgid, IPC_RMID, NULL)