0

私はこのテスト CGI プログラムを C で書きました。

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

Web サーバーに Apache を使用しています。ブラウザで「localhost/cgi-bin/mycgi」に移動したとき(同時に2つのタブを開きます)。

出力は次のようになります (予想)

(Tab1 の場合) 「すべて PID によって行われました - 8186」

および(Tab2の場合)「すでに実行中」

しかし、私はこれを取得します(実際)

(Tab1 の場合) 「すべて PID によって行われました - 8186」

および(Tab2の場合)「すべてPIDによって行われた-8187」

端末でプログラム (2 つのインスタンス) を実行すると、上記のコードは期待どおりに動作します。

4

2 に答える 2

0

わかりました、ここで私の質問に対する答えを見つけました。

ブラウザは、サーバーへの1つの接続を開き、同じ接続を使用して複数の要求を送信する場合があります。それがいわゆる「キープアライブ」接続です。サーバー側では、これにより、この1つの接続が1つのApache「子」に渡され、この1つの子が接続を開いたままにして、その接続上のすべての要求を次々に処理します。

同じブラウザで開いているウィンドウまたはタブの数に関係なく、すべてのウィンドウまたはタブに対して、その1つの接続のみを使用している可能性があります。ただし、2つの異なるブラウザー(または2つの異なるワークステーション上の同じブラウザー)は、1つの接続を共有しません。

これを2つの異なるブラウザ(FirefoxとChrome)で同時に試してみると、期待どおりに機能します。

于 2012-10-29T09:04:27.600 に答える
0

Ubuntu からman sem_overview:

名前付きセマフォは、/somename という形式の名前で識別されます。つまり、最初のスラッシュの後に 1 つ以上の文字が続き、いずれもスラッシュではない、最大 NAME_MAX-4 (つまり 251) 文字のヌル終了文字列です。

IOW、セマフォ名が無効です。

からの別のことman sem_open

O_CREAT が oflag で指定されている場合、2 つの追加の引数を指定する必要があります。...

modeこの関数は、およびのようにランダムながらくたを取得valueし、予測可能な予測不可能な結果を​​もたらします。

于 2012-10-28T13:56:18.197 に答える