最近在项目中发现了一个关于线程退出的问题.
启动线程的代码为
pthread_create(&thread, NULL, Push, NULL);
线程函数Push的实现如下:
void * Push()
{
//创建服务器代码省略
int clientFd = accept(serverFd, (struct sockaddr *)&client_addr, (socklen_t *)&sin_size);
while(isStart)
{
//业务逻辑
}
}
当我想让线程退出时,我直接将isStart置为false,我当时认为线程函数就会判断到isStart不为true就会跳出while循环并结束。在使用中很长时间没有出现过问题,直到某一天我在写测试用例时发现,如果我启动这个线程后没有客户端连接,当我想要线程退出时,把isStart置为false,线程没有退出,主进程一直处于等待线程退出状态。
一番排查后发现是因为accept采用的是阻塞等到客户端连接,也就是说根本没有执行到while循环,自然也不会判断isStart的值。
最后的解决方法是使用pthread_cancel让线程退出。具体代码如下:
//线程部分的代码不变
void Stop()
{
isStart = false;
int err = pthread_cancel(thread);
pthread_join(thread, NULL);
//关闭端口
return;
}
修改之后,无论有没有客户端连接,都可以让线程退出。