我正在学习Pthreads,并想知道杀死这样一个物体的最佳方法是什么。在寻找类似问题之后,我无法找到“明确”的答案,但请随时向我指出任何相关问题。
我正在使用一个小型客户端服务器应用程序,其中服务器主要的线程正在侦听客户端连接的套接字。每次客户端连接时,服务器都会在while循环中创建一个执行“无限工作”的新线程。现在我想在同一个客户端在套接字上发送“停止”请求时停止此循环。
如果知道通过每个套接字消息中提供的ID识别客户端,您将如何实现此类行为?使用共享变量(在主服务器线程和客户端服务器线程之间)作为while循环中的tes条件。使用PThread功能?
答案 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);
}