0

我已经用 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 个实例),上述代码将按预期工作。

4

2 回答 2

0

好的,我在这里找到了我的问题的答案。

浏览器可能会打开一个与服务器的连接,并使用同一连接发送多个请求。这就是所谓的“保持活动”连接。在服务器端,这导致这个连接被移交给一个单独的 Apache“子”,并且这个单独的子保持连接打开并处理该连接上的所有请求,一个接一个。

无论您在同一个浏览器中打开多少个窗口或选项卡,它可能仍然只使用一个连接,用于所有窗口或选项卡。但是两个不同的浏览器(或两个不同工作站上的同一个浏览器)不会共享一个连接。

如果我同时在两个不同的浏览器(Firefox 和 Chrome)中尝试这个,它会按预期工作。

于 2012-10-29T09:04:27.600 回答
0

来自 Ubuntu 的man sem_overview

命名信号量由 /somename 形式的名称标识;即,最多 NAME_MAX-4(即 251)个字符的空终止字符串,由一个初始斜杠组成,后跟一个或多个字符,其中没有一个是斜杠。

IOW,您的信号量名称无效。

另一件事,来自man sem_open

如果在 oflag 中指定了 O_CREAT,则必须提供两个附加参数。...

该函数将得到随机的废话modevalue,并具有可预测的不可预测的结果。

于 2012-10-28T13:56:18.197 回答