0

私はマルチスレッド プログラミングの概念を理解しようとしており、うまくやっていると思いますが、単純なechoサーバーの次のコードを見つけました。

http://www.cs.utah.edu/~swalton/listings/sockets/programs/part2/chap7/echo-thread.c

mainそして、同じローカル変数を使用して各着信接続のデータ ソケットを格納するため、コードが間違っていると考えています。特に、次の部分が気になりmain()ます。

while (1)
{   int client, addr_size = sizeof(addr);
    pthread_t child;

    client = accept(sd, (struct sockaddr*)&addr, &addr_size);
    printf("Connected: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
    if ( pthread_create(&child, NULL, Child, &client) != 0 )
        perror("Thread creation");
    else
        pthread_detach(child);  /* disassociate from parent */
}

私が理解している限り、ループclientに対してローカルな変数whileは、ループの各反復でまったく同じアドレスに割り当てられます。そのため、最初のクライアントが受け入れられると、スレッドは を受け取り&client、2 番目のクライアントが受け入れられると、 の値がclient新しいデータ ソケットで上書きされます。これにより、最初のクライアントで既に実行されているスレッドに副作用が生じる可能性があります。 .

関数のコード (Childサービス スレッド) を観察すると、引数がローカル変数にコピーされていることがわかります。

void* Child(void* arg)
{   char line[100];
    int bytes_read;
    int client = *(int *)arg;
    ...etc...

おそらく作者は、このコピーによって後でメイン変数を改ざんできると考えていましたclientが、私見では、これにより競合状態が発生する可能性があります。最初のスレッドがこの変数をコピーしている間に 2 番目のクライアントが到着すると、コピーされた値が破損する可能性があります。

私は正しいですか?

4

2 に答える 2

1

はい。それで合っています。これを修正するには、2 つの明白な方法があります。

  1. clientの代わりにスレッドに渡し&clientます。

  2. ヒープに新しい整数を割り当て、そのアドレスをスレッドに渡し、処理が完了したらスレッドに解放させます。

于 2013-02-10T22:11:54.513 に答える
1

はい、あなたは正しいです。

sleep最初のクライアント スレッド中にずっと前に追加int client = *(int*)arg;し、サーバーに 2 回接続することで、あなたが正しいことを示すことができます。

于 2013-02-10T22:13:35.457 に答える