我已经用C语言编写了这个测试CGI程序。
int main(int argc, char *argv[])
{
sem_t *mysem;
mysem = sem_open("/MyClient", O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 10);
if(mysem == SEM_FAILED)
{
// already running
if(errno == EEXIST)
{
fprintf(stdout, "Content-type:text/plain\n\n");
fprintf(stdout, "Already running");
exit(1);
}
else
{
fprintf(stdout, "[error] - ", errno);
exit(1);
}
}
fprintf(stdout, "Content-type:text/plain\n\n");
int i = 0;
for(;i <10; i++)
{
sleep(1);
}
fprintf(stdout, "all done by PID - %d\n", getpid());
sem_unlink("MyClient");
sem_close(mysem);
return 0;
}
我正在使用Apache进行Web服务器。 当我在浏览器中转到“localhost / cgi-bin / mycgi”时(我同时打开两个标签页)。
输出应该是这样的(预期的)
(对于Tab1) “全部由PID - 8186完成”
和(对于Tab2)“已经在运行”
但我得到了这个(实际的)
(对于Tab1) “全部由PID - 8186完成”
和(对于Tab2)“所有由PID完成 - 8187”
如果我在终端中执行程序(2个实例),上面的代码会按预期工作。
答案 0 :(得分:0)
来自Ubuntu的man sem_overview
:
命名信号量由表单名称/ somename标识;那 是一个以空字符结尾的字符串,最多为NAME_MAX-4(即251) 由初始斜杠组成的字符,后跟一个或多个 字符,没有一个是斜杠。
IOW,您的信号量名称无效。
另一件事,来自man sem_open
:
如果在oflag中指定了O_CREAT,那么必须有两个额外的参数 提供。 ...
该函数将随机排除mode
和value
,结果具有可预测的不可预测性。
答案 1 :(得分:0)
好的,我找到了问题here的答案。
浏览器可以打开与服务器的单个连接,并使用相同的连接发送多个请求。这就是所谓的“保持活跃”的连接。在服务器端,这导致这一个连接被移交给一个单独的Apache“子”,并且这个单个子节点保持连接打开并一个接一个地处理该连接上的所有请求。
无论您在同一浏览器中打开多少个窗口或标签,可能仍然只使用该连接,用于其所有窗口或标签。但是两个不同的浏览器(或两个不同工作站上的相同浏览器)不会共享一个连接。
如果我同时在两个不同的浏览器(Firefox和Chrome)中试用它,它会按预期工作。