2

我正在学习 Pthreads,并且想知道杀死这样一个对象的最佳方法是什么。在寻找类似问题后,我无法找到“明确”的答案,但请随时向我指出任何相关问题。

我正在使用一个小型客户端服务器应用程序,其中服务器主线程正在侦听客户端连接的套接字。每次客户端连接时,服务器都会在 while true 循环中创建一个执行“无限工作”的新线程。现在我想在同一个客户端在套接字上发送“停止”请求时停止这个循环。

知道客户端是通过每个套接字消息中提供的 ID 来识别的,您将如何实现这样的行为?使用共享变量(在主服务器线程和客户端服务器线程之间)作为 while 循环中的测试条件。使用 PThread 函数?

4

3 回答 3

3

没有办法强行杀死单个 POSIX 线程;这是故意的,设计使然。相反,如果您的线程需要被其他线程停止,您应该设计在其中运行的代码以考虑到这一点。执行此操作的惯用方法是使用退出标志变量(受互斥体保护)和条件变量。

还有pthread_cancel, 可用于请求线程退出。正确使用它需要设置清理处理程序pthread_cleanup_push和/或临时禁用取消pthread_setcancelstate

于 2012-08-20T01:18:38.403 回答
2

您不应该强制线程退出。您应该设计您的程序,以便在发送“停止”时存在 while 循环。

就像是:

  while(strcmp(word, "stop")!=0){
        word = read_word_from_socket();
        ......
  }
于 2012-08-19T19:14:36.443 回答
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 回答