<?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;
}