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\n"); } int main(int argc, char **argv) { if(argc != 3){ fprintf(stderr, "usage: %s 进程数 consumer脚本路径\n", argv[0]); exit(1); } int p_num = atoi(argv[1]); if(p_num <= 0 || p_num > 96){ fprintf(stderr, "1 <= 进程数 <= 96\n"); 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("全部脚步已经退出\n"); break; }else{ printf("已经有%d个脚本退出...\n", (p_num - (int)ds.msg_qnum)); sleep(1); } } return 0; }