2

私は Pthreads を学んでいて、そのようなオブジェクトを殺す最良の方法は何かと思っていました。同様の質問を探した後、「明確な」答えを見つけることができませんでしたが、関連する質問を教えてください。

サーバーのメインスレッドがクライアント接続のソケットをリッスンしている小さなクライアントサーバーアプリケーションを使用しています。クライアントが接続するたびに、サーバーは while true ループで「無限の作業」を実行する新しいスレッドを作成します。同じクライアントがソケットで「停止」要求を送信したときに、このループを停止したいと考えています。

各ソケット メッセージ内で提供される ID によってクライアントが識別されることを知っていれば、このような動作をどのように実装しますか? while ループの tes 条件として (メイン サーバー スレッドとクライアント サーバー スレッドの間で) 共有変数を使用する。PThread 関数を使用していますか?

4

3 に答える 3

3

1 つの POSIX スレッドを強制的に終了する方法はありません。これは意図的なものです。代わりに、スレッドが他のスレッドによって停止可能である必要がある場合は、これを考慮して実行するコードを設計する必要があります。これを行う慣用的な方法は、終了フラグ変数 (mutex によって保護されている) と条件変数を使用することです。

pthread_cancelスレッドの終了を要求するために使用できるもあります。正しく使用するには、 でクリーンアップ ハンドラを設定するpthread_cleanup_pushか、 でキャンセルを一時的に無効にする必要がありますpthread_setcancelstate

于 2012-08-20T01:18:38.403 に答える
1

次のようにサーバーを設計できます。

typedef struct _client_data_buffer
{
   char user_cmd[16];    /* Could be "CONTINUE" or "STOP" */
   char* buffer;         /* Client network data. You can use a fixed size buffer for this part also */
} client_data_buffer;

/* client encode data before sending to the server */
size_t encode_client_data(client_data_buffer* data_buf, char* buf)
{
    size_t serialized_bytes = 0;    /* Can help for transmission errors checking */

    /* Serialize the cmd */
    memcpy(buf + serialized_bytes, data_buf->user_cmd, strlen(data_buf->user_cmd) + 1);
    serialized_bytes += strlen(data_buf->user_cmd) + 1;
    /* Serialize the data the client want to send to the server */
    memcpy(buf + serialized_bytes, data_buf->buffer, strlen(data_buf->buffer) + 1);
    serialized_bytes += strlen(arch->nombre_arch) + 1;

    return serialized_bytes;
}

/* Server decode client data */
void decode_client_data(char* buf, client_data_buffer* data_buf)
{
    /* Your decode here */
}

int create_server(int port, char *address)
{
    /* Create you server */
}

void* thread_callback(void *client_data)
{
    /* client socket descriptor */
    int client_id = *(int *) client_data;
    client_data_buffer *some_user_data;
    char some_buffer[BUFFER_SIZE];

    /* receiving data until STOP command is received */

    while(1)
    {
        /* receive */
        recv(client_id, some_buffer, BUFFER_SIZE, 0);

        /* decode some_buffer to some_user_data */

        /* compare */
        if (strcmp("STOP", some_user_data->user_cmd) == 0)
        {
            /* shutdown and close client socket and exit */
        }

        else
        {
            /* Parse incoming data and do the job */
        }
    }

    return NULL;
}

int main(int argc, char **argv) {
    int server_socket;
    int client_socket;
    int result;

    /* Crete our server */
    server_socket = create_tcp_server (my_port_number, my_address);

    while (1) {
        pthread_t thread_id;

        client_socket = accept(server_socket, NULL ,NULL);
        result = pthread_create(&thread_id, NULL, thread_callback, (void *) client_socket);
        if (result != 0) 
        {
          /* Handle errors with errno and exit */
        }
        /* We don't care about the return status ---> avoid zombies and handling threads termination */
        pthread_detach(thread_id);
    }

    exit (EXIT_SUCCESS);
}
于 2012-08-20T00:57:47.907 に答える