PHP和C语言共享内存通信以及信号量互斥

2010-05-24 21:53 / 6 comments / 243 views /

程序分PHP部分和C语言部分。PHP部分提供一个run_php_cmd函数入口参数为命令直接返回C语言处理结果。C语言部分提供一个run_php_cmd入口参数为一个函数,当收到PHP命令时调用该函数。

动作流程为:PHP往共享内存里写数据->释放cmd信号量->C语言从共享内存里读数据->C语言向共享内存里写返回结果->C语言释放ret信号量->PHP等到ret信号量得到返回结果

C语言信号量操作

pv.h:
int sem_creat(key_t key);//生成信号量
void del_sem(int semid);//删除信号量
inline int v(int semid);//v v操作
inline int p(int semid);//p p操作
 pv.c:
#include <sys/sem.h>
#include <stdio.h>
#include "pv.h"
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
};
//生成信号量
int sem_creat(key_t key)
{
union semun sem;
int semid;
sem.val = 0;
semid = semget(key,1,IPC_CREAT|0666);
if (-1 == semid){
printf("create semaphore error\n");
return 0;
}
semctl(semid,0,SETVAL,sem);
return semid;
}
//删除信号量
void del_sem(int semid)
{
union semun sem;
sem.val = 0;
semctl(semid,0,IPC_RMID,NULL);
}
//v v操作
inline int v(int semid)
{
struct sembuf sops={0,+1,0};
return (semop(semid,&sops,1));
}
//p p操作
inline int p(int semid)
{
struct sembuf sops={0,-1,0};
return (semop(semid,&sops,1));
}
#include <sys/sem.h>#include <stdio.h>
#include "pv.h"
union semun { int val; struct semid_ds *buf; unsigned short *array;};
//生成信号量
int sem_creat(key_t key){
	union semun sem;
	int semid;
	sem.val = 0;
	semid = semget(key,1,IPC_CREAT|0666);
	if (-1 == semid){
		printf("create semaphore error\n");
		return 0;
	}
	semctl(semid,0,SETVAL,sem);
	return semid;
}
//删除信号量
void del_sem(int semid){
	union semun sem;
	sem.val = 0;
	semctl(semid,0,IPC_RMID,NULL);
}
//v v操作
inline int v(int semid){
	struct sembuf sops={0,+1,0};
	return (semop(semid,&sops,1));
}
//p p操作
inline int p(int semid){
	struct sembuf sops={0,-1,0};
	return (semop(semid,&sops,1));
}

C语言创建共享内存以及处理PHP命令

php.h:
#ifndef _PHP_IPCKEY
#define _PHP_IPCKEY 0x0127
#endif
extern int run_php_cmd(int (*do_php_cmd)(void *));
php.c:
#include <sys/shm.h> #include <memory.h>  #include "pv.h" #include "php.h"  void * php;  int cmd_sem; int ret_sem;  static int php_setup(int ipckey) { 	int shmid;  	shmid = shmget(ipckey,1024,IPC_CREAT|0666); 	if(shmid == -1){ 		return -1; 	} 	php = (char *)shmat(shmid,0,0); 	if((int)php == -1) { 		return -1; 	}  	cmd_sem = sem_creat(ipckey); 	ret_sem = sem_creat(ipckey + 1);  	memset(php,0,1024);  	return 0; }  inline int php_wait_cmd(void) { 	return p(cmd_sem); }  inline int php_wait_ret(void) { 	return p(ret_sem); }  inline int php_send_ret(void) { 	return v(ret_sem); }  int run_php_cmd(int (*do_php_cmd)(void *)){ 	int i = 0;  	if(php_setup(_PHP_IPCKEY)){ 		return -1; 	}  	if(do_php_cmd == NULL) return -2;  	while(i >= 0){ 		php_wait_cmd(); 		for(i = 0; i < 1024; i++){ 			char *c = (char *)php + i; 			if(*c == ';') { 				*c = 0; 				break; 			} 		} 		i = (* do_php_cmd)(php); 		php_send_ret(); 		php_wait_ret(); 	}  	del_sem(cmd_sem); 	del_sem(ret_sem); 	return -i; }

PHP发送命令并输出C语言处理结果

<?php
function run_php_cmd($cmd){
$ipckey = 0×0127;
$cmd_sem = sem_get($ipckey);
$ret_sem = sem_get($ipckey+1);
$shm_sem = sem_get($ipckey+2);
$shmid = shmop_open($ipckey, “w”, 0666, 1024);
$cmd .= “\0;”;
if(sem_acquire($shm_sem)){
shmop_write($shmid, $cmd, 0);
@sem_release($cmd_sem);
if(sem_acquire($ret_sem) && sem_acquire($ret_sem)){
$i = 0;
while($i < 1024){
$c = shmop_read($shmid, $i, 1);
if(!strcmp($c,”\0″)) break;
echo($c);
$i = $i+1;
}
}
}
sem_release($shm_sem);
shmop_close ($shmid );
}
?>

Related Posts

  1. Linux下Socket通信、共享内存和信号量混合使用的例子
  2. GetSystemInfo Function
  3. Linux下用户态直接读写磁盘扇区
  4. C语言HTML解析器
  5. 线性表
  6. Linux下原生异步IO接口Libaio的用法
  7. PHP实现缓存(cache)的方法
  8. Go语言中通过结构体匿名字段实现方法的继承和重载
  9. 读btrecord源代码
  10. 删除一个字符串中的空格

Tags: , , , .

Get a Trackback link

6 Comments

  1. niubi2010年5月25日 12:23:

    恩,不错!来了留个小脚丫,呵呵

  2. 无聊2010年5月26日 13:18:

    呵呵,强悍。。

  3. hatsune2011年4月3日 0:33:

    lz你这个程序行不通阿。。。php根本就不是像c那样设计共享内存区和信号量的,你这样能成功的几率相当小。。。

  4. Jian Zhou2011年4月4日 17:09:

    程序是行得通的,但是压力大了会有问题,把信号量改成socket通信就稳定了

  5. hatsune2011年4月5日 23:53:

    呵呵,首先行得通是行得通,这我肯定你。但确实像你说的那样不稳定,你也说信号量有问题,php里面定义的是一个system v信号量集里面三个信号量,所以即使是key值一样也会有问题。共享内存区也是一样,php用system v做了自己的共享内存区,如果直接用映射地址访问就会出问题。。。

  6. Jan Zhou2011年4月6日 17:26:

    @hatsune, 你知道问题在哪?我仔细调过,感觉是php里的信号量机制的问题。你有办法让这种通信方式变稳定吗?

Leave a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>