php通过消息队列IPC跟C语言进程简单通信

<?php
function ftok2($pathname, $proj_id) { 
        $st = @stat($pathname); 
        if (!$st) { 
                return -1; 
        } 
        $key = sprintf("%u", (($st['ino'] & 0xffff) | (($st['dev'] & 0xff) << 16) | (($proj_id & 0xff) << 24)));
        return $key; 
}

$key = ftok2("/root/unix/wangyi/src/ipc/bin", "23");

if(msg_queue_exists($key)){
        $queue = msg_get_queue($key);

        $ret = msg_receive($queue, 0, $type, 1024, $msg, false, MSG_IPC_NOWAIT);

        var_dump($ret);
        var_dump($msg);
}
/**
 *  通过消息队列使php脚本进行扫尾工作然后退出
 *  一般通过发送信号即可,但由于consumer脚本收到信号会莫名的退出(还没有定位到原因)
 */
#include <stdio.h>
#include <stdlib.h>
#include <sys/msg.h>
#include <signal.h> 
#include <sys/types.h>
#include <unistd.h>

/* global variables */
int msg_id = 0;

typedef struct{
        int type;
        char mtext[128];
} MSG;

void sig_handler(int signo)
{
        exit(0);
}

__attribute__((constructor)) void _construct(void)
{
        signal(SIGINT, sig_handler);
}

__attribute__((destructor)) void _destruct(void)
{
        //rm msg queue
        if(msg_id != 0){
                msgctl(msg_id, IPC_RMID, NULL);
        }
        printf("__destructor
");
}

int main(int argc, char **argv)
{
        if(argc != 3){
                fprintf(stderr, "usage: %s 进程数 consumer脚本路径
", argv[0]);
                exit(1);
        }
        int p_num = atoi(argv[1]);
        if(p_num <= 0 || p_num > 96){
                fprintf(stderr, "1 <= 进程数 <= 96
");
                exit(1);
        }
        //create msg queue
        key_t key = ftok("/root/unix/wangyi/src/ipc/bin", 23);
        if((msg_id = msgget(key, IPC_CREAT | IPC_EXCL | 0644)) < 0){
                perror("msgger error");
                exit(2);
        }
        //send msg
        int n;
        MSG m = {1, "php script exit"};
        for(n = 0; n < p_num; n++){
                if(msgsnd(msg_id, &m, sizeof(MSG) - sizeof(long), IPC_NOWAIT) < 0){
                        perror("msgsnd error");
                        exit(3);
                }
        }
        //wait php receive
        struct msqid_ds ds;
        while(1){
                if(msgctl(msg_id, IPC_STAT, &ds) < 0){
                        perror("msgctl error");
                        exit(4);
                }
                if(ds.msg_qnum == 0){
                        printf("全部脚步已经退出
");
                        break;
                }else{
                        printf("已经有%d个脚本退出...
", (p_num - (int)ds.msg_qnum));
                        sleep(1);
                }
        }


        return 0;
}
原文地址:https://www.cnblogs.com/bai-jimmy/p/6284539.html