0

彼ら!

* nixの下でcでマルチスレッドサーバーを開発しています。プロセスのメイン スレッドには、接続を待機するリッスン ソケットがあります (受け入れます)。接続を取得すると (accept はクライアント ソケット記述子を返します)、要求に応答してクライアント ソケット記述子を閉じるルーチンで新しい pthread を開始します。次のようになります。

while(1)
{
    sock_cl =(int *)malloc(sizeof(int));
    *sock_cl = accept(sock_serv, NULL, NULL);
    pthread_create(thread, attr, answer, sock_cl);
}

回答機能:

void *answer(void *arg)
{
    int sock_cl;
    char *buf;
    ssize_t r;
    lsres_t *ans;
    char *path;
    char status[STATUS_SIZE];

    sock_cl = *((int *)arg);
    if((buf = (char *)malloc(BUF_SIZE + 1)) == NULL)
    {
        sprintf(status, "%i\n", -1);
        send_data(sock_cl, status, STATUS_SIZE);
        close(sock_cl);
        free(arg);
        return NULL;
    }
    memset(buf, '\0', BUF_SIZE + 1);

    if((r = recv(sock_cl, buf, BUF_SIZE, 0)) <= 0)
    {
        close(sock_cl);
        free(arg);
        return NULL;
    }

    path = strtok(buf, "\r\0");
    if((ans = lscreate()) == NULL)
    {
        sprintf(status, "%i\n", -1);
        send_data(sock_cl, status, STATUS_SIZE);
    }
    else
    {
        if(myls(path, ans) != 0)
        {
            sprintf(status, "%i\n", -1);
            send_data(sock_cl, status, STATUS_SIZE);
        }
        else
        {
            sprintf(status, "%i\n", ans->status);
            send_data(sock_cl, status, STATUS_SIZE);
            send_data(sock_cl, ans->buf, ans->written_size);
        }
        lsdestroy(ans);
    }

    close(sock_cl);
    free(arg);
    return NULL;
}

answer 関数では、recv を呼び出してクライアントからデータを受信し、回答を送信します。Linux システム (Arch、Debian、Ubuntu) では正常に動作しますが、Unix (Solaris) で実行しようとすると、recv 関数でセグメンテーションが低下します。回答関数と同じスレッドで回答関数を呼び出そうとすると、セグメンテーション フォールがないため、問題はバッファ内にありません。そのため、pthread でソケットを使用する際にいくつかの問題があります。

マルチスレッドサーバーでソケットを使用する方法を教えてください。今後とも回答よろしくお願いします!

4

3 に答える 3

1

Solaris では、通常-mt、マルチスレッド プログラムを正しくコンパイルおよびリンクするには、 でコンパイルする必要があります。使用しないと、ご覧のようにスレッドでランダムなクラッシュが発生します。

于 2013-05-12T21:02:34.377 に答える
0

UNIX では recv 関数が失敗し、セグメンテーション障害はコード セグメントが原因であると思いますfree(args);

于 2013-05-12T14:47:22.670 に答える
-1

これが原因かも

   close(sock_cl);
    free(arg);
    return NULL;

この sock_cl はスレッド間で共有されます。応答関数の同期がなく、クラッシュする他のスレッドにバインドされているこのポインターを解放しているため、可能であれば、valgrind で実行して破損がないかどうか、この同じプログラムをチェックインします。

于 2013-05-12T14:52:34.330 に答える