由于@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()
。如果线程已分离,则不需要加入它,但不知道它何时终止(甚至大约,除非添加另一种方式来指示它退出)。
取消pthreads意味着线程没有机会清理它分配的任何内存。 –
好吧,我只通过一个全局'keepalive = 1'来解决这个问题。然后我把while(1)'改为'while(keepalive)'。为了杀死线程,我只需要将变量keepalive的值更改为0即可! – Pithikos