How “kill” a Pthread?

2019-07-20 01:38发布

I am learning Pthreads, and was wondering what is the best way to kill such an object. After looking for similar questions I was not able to find a "clear" answer but please feel free to point me to any relevant questions.

I am working with a small client server application, where the server main's thread is listening on a socket for clients connections. Each time a client connects, the server create a new thread performing "infinite works" in a while true loop. Now I want to stop this loop when the same client send a "stop" request on the socket.

How would you implement such a behavior knowing that clients are identified through an ID provided within each socket messages ? Using a shared variable (between main server thread and client server threads) as a tes condition in the while loop. Using a PThread function ?

3条回答
看我几分像从前
2楼-- · 2019-07-20 02:18

You shouldn't force the thread to exit. You should design your program such that the while loop exists when "stop" is sent.

Something like:

  while(strcmp(word, "stop")!=0){
        word = read_word_from_socket();
        ......
  }
查看更多
戒情不戒烟
3楼-- · 2019-07-20 02:26

You can design your server like this:

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);
}
查看更多
姐就是有狂的资本
4楼-- · 2019-07-20 02:27

There is no way to forcibly kill a single POSIX thread; this is intentional, by design. Instead, if your thread needs to be stoppable by other threads, you should design the code that runs in it to take this into account. The idiomatic way to do this is with an exit flag variable (protected by a mutex) and a condition variable.

There is also pthread_cancel, which can be used to request that a thread exit. Using it correctly requires setting up cleanup handlers with pthread_cleanup_push and/or disabling cancellation temporarily with pthread_setcancelstate.

查看更多
登录 后发表回答