如何“杀死”Pthread?

时间:2012-08-19 19:07:26

标签: c sockets pthreads client-server

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

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

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

3 个答案:

答案 0 :(得分:2)

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

类似的东西:

  while(strcmp(word, "stop")!=0){
        word = read_word_from_socket();
        ......
  }

答案 1 :(得分:2)

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

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

答案 2 :(得分: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);
}