我创建了一个线程并将其放入无限循环中。使用 valgrind 检查代码时出现内存泄漏。这是我的代码:
#include <pthread.h>
#include <time.h>
void thread_do(void){
while(1){}
}
int main(){
pthread_t th;
pthread_create(&th, NULL, (void *)thread_do, NULL);
sleep(2);
/* I want to kill thread here */
sleep(2);
return 0;
}
因此在 main 中创建了一个线程,并且一直运行 thread_do()。有没有办法在 2 秒后从 main 中杀死它?我已经尝试了 pthread_detach(th)
和 pthread_cancel(th)
但我仍然遇到泄漏。
最佳答案
正如@sarnold 所指出的,默认情况下,如果不调用任何作为取消点的函数,您的线程将无法通过 pthread_cancel()
取消...但这可以通过使用 来更改pthread_setcanceltype()
将线程的取消类型设置为异步而不是延迟。为此,您需要在开始循环之前,在线程函数的开头附近添加类似 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
的内容。然后,您可以通过从 main()
调用 pthread_cancel(th)
来终止线程。
但请注意,以这种方式取消线程(无论是否异步)不会清除线程函数中分配的任何资源(正如 Kevin 在评论中指出的那样)。为了干净利落地做到这一点,您可以:
- 确保线程在退出前不做任何需要清理的事情(例如使用
malloc()
分配缓冲区) - 确保在线程退出后,您有一些方法可以在其他地方清理线程
- 使用
pthread_cleanup_push()
和pthread_cleanup_pop()
添加清理处理程序以在线程被取消时清理资源。请注意,如果取消类型是异步的,这仍然存在风险,因为线程可能会在分配资源和添加清理处理程序之间被取消。 - 避免使用
pthread_cancel()
并让线程检查一些条件以确定何时终止(这将在长时间运行的循环中检查)。由于您的线程随后会自行检查是否终止,因此它可以在检查后进行任何需要的清理工作。
实现最后一个选项的一种方法是使用互斥锁作为标志,并使用包装在循环测试中使用的函数中的 pthread_mutex_trylock()
对其进行测试:
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
/* Returns 1 (true) if the mutex is unlocked, which is the
* thread's signal to terminate.
*/
int needQuit(pthread_mutex_t *mtx)
{
switch(pthread_mutex_trylock(mtx)) {
case 0: /* if we got the lock, unlock and return 1 (true) */
pthread_mutex_unlock(mtx);
return 1;
case EBUSY: /* return 0 (false) if the mutex was locked */
return 0;
}
return 1;
}
/* Thread function, containing a loop that's infinite except that it checks for
* termination with needQuit()
*/
void *thread_do(void *arg)
{
pthread_mutex_t *mx = arg;
while( !needQuit(mx) ) {}
return NULL;
}
int main(int argc, char *argv[])
{
pthread_t th;
pthread_mutex_t mxq; /* mutex used as quit flag */
/* init and lock the mutex before creating the thread. As long as the
mutex stays locked, the thread should keep running. A pointer to the
mutex is passed as the argument to the thread function. */
pthread_mutex_init(&mxq,NULL);
pthread_mutex_lock(&mxq);
pthread_create(&th,NULL,thread_do,&mxq);
sleep(2);
/* unlock mxq to tell the thread to terminate, then join the thread */
pthread_mutex_unlock(&mxq);
pthread_join(th,NULL);
sleep(2);
return 0;
}
如果线程没有分离(默认情况下通常不是),您应该在停止线程后调用 pthread_join()
。如果线程是分离的,您不需要加入它,但您不会确切知道它何时终止(或什至大约知道,除非您添加另一种方式来指示它的退出)。
关于c - 我怎样才能从那个循环之外杀死一个处于无限循环中的 pthread?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7961029/