我有一个 PHP 代码与 CPP 应用共享内存,PHP 是生产者,CPP 是消费者。 我正在处理这些事情,但我发现有时代码会搞砸并且不能正常工作,因为我稍微研究了一下,我发现 PHP 信号量实际上是一个 3 信号量对象,所以这可能是这里的问题。 我需要一种方法在两个代码之间建立互斥并避免此类问题。
这是我的 PHP 代码示例:
if (!$sem_id = sem_get($sem_key)) {
echo "Could not get ID for the semaphore.\n";
} else {
if (!sem_acquire($sem_id)) {
echo "failed.\n";
} else {
//echo "Sem ID: " . $sem_id . "<br/>";
if ($shm = shmop_open($shm_key, "c", 0666, 1048576)) {
$count = unpack('L', shmop_read($shm, 0, 4));
$count = reset($count);
$count++;
shmop_write($shm, pack('L', $count), 0);
shmop_write($shm, pack('L', $section_id) . $data, 4 + ($count-1) * 30);
} else {
echo "Couldnt't open shmop.";
}
sem_release($sem_id);
}
}
对于 CPP 应用程序,我使用了我发现的这个函数:
static int semaphore1_get_access(void)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = -1; /* P() */
sem_b.sem_flg = SEM_UNDO;
if (semop(semaphore1_id, &sem_b, 1) == -1) //Wait until free
{
fprintf(stderr, "semaphore1_get_access failed\n");
return(0);
}
return(1);
}
static int semaphore1_release_access(void)
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = 1; /* V() */
sem_b.sem_flg = SEM_UNDO;
if (semop(semaphore1_id, &sem_b, 1) == -1)
{
fprintf(stderr, "semaphore1_release_access failed\n");
return(0);
}
return(1);
}
正如我所说,我认为这里的问题是 PHP 处理信号量的方式,如果有人知道如何调整该函数以与 PHP 函数兼容,我将非常感激。
谢谢大家的帮助!
最佳答案
好吧,在尝试了很多事情之后。 这种方式似乎已经解决了问题:
static int semaphore1_get_access(int num)
{
struct sembuf sops[3]; //struct sembuf *sops = (struct sembuf *) malloc(3*sizeof(struct sembuf));
sops[0].sem_num = 0;
sops[0].sem_op = -1; /* P() */
sops[0].sem_flg = SEM_UNDO;
sops[1].sem_num = 1;
sops[1].sem_op = 1; /* P() */
sops[1].sem_flg = SEM_UNDO;
if (semop(semaphore1_id, sops, 2) == -1) //Wait until free
{
fprintf(stderr, "semaphore1_get_access failed\n");
return(0);
}
return(1);
}
static int semaphore1_release_access(int num)
{
struct sembuf sops[3];// = (struct sembuf *) malloc(3*sizeof(struct sembuf));
sops[0].sem_num = 0;
sops[0].sem_op = 1; /* P() */
sops[0].sem_flg = SEM_UNDO;
sops[1].sem_num = 1;
sops[1].sem_op = -1; /* P() */
sops[1].sem_flg = SEM_UNDO;
if (semop(semaphore1_id, sops, 2) == -1) //Wait until free
{
fprintf(stderr, "semaphore1_get_access failed\n");
return(0);
}
return(1);
}
我没有使用第三个信号量,但我不知道这是否会产生后果。
我找到了有关 PHP 处理信号量的方式的信息: http://www.serverphorums.com/read.php?8,313695
我发现有用的是 3 组中的第一个信号量是真实信号量,是否阻塞进程, 第二个用于了解有多少进程正在访问信号量 第三个用于控制对第二个信号量的访问。
关于与 Ubuntu 中的 CPP 应用程序兼容的 PHP 信号量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22642968/