在工作中遇到一个问题:在程序中需要创建一个线程,间隔若干秒循环地监测某个变量,并且能够随时的终止这个线程,同时又需要保证线程的唯一性。
在此把相关的逻辑抽离出来,总结的代码如下:
/* 创建及终止一个线程,同时保证线程的唯一性 */
static pthread_t test_tid;
//线程函数
static void *test_thread(void *arg)
{
while(1)
{
sleep(3);
printf("%s: running.\n", __func__);
pthread_testcancel(); //创建一个取消点
}
pthread_exit(NULL); //线程正常退出
return NULL;
}
//创建检测线程
void create_test_thread(unsigned int *exist_flag)
{
if(*exist_flag)
return;
int err;
err = pthread_create(&test_tid, NULL, test_thread, NULL); //创建线程
if (err != 0)
{
printf(">>>> Can't create thread: %s\n", strerror(err));
return;
}
*exist_flag = 1;
printf(">>>> %s: created thread - tid = %d\n", __func__, test_tid);
}
//终止检测线程
void destroy_test_thread(unsigned int *exist_flag)
{
if(!(*exist_flag))
return;
void *ret = NULL;
//取消线程,等待它结束
pthread_cancel(test_tid);
pthread_join(test_tid, &ret);
*exist_flag = 0;
printf(">>>> %s: the test thread %d exit, exit code %d\n", __func__, test_tid, (int)ret);
}
这里值得一提的几点:
1. pthread_cancel() 函数以及 pthread_testcancel() 函数的配合使用:当调用pthread_cancel() 时,线程函数并不会立即终止;调用pthread_cancel() 之后,线程函数做 testcancel 的检查通过之后才终止。
2. 为了保证线程的唯一性(不重复创建线程,不试图终止不存在的线程),这里设置了 exist_flag 这个参数来传入线程的创建及终止函数(这里有点像“信号量”的概念)。可以在主函数中设置一个全局的 g_ExistFlag,当线程被创建时 g_ExistFlag 被置一,销毁时则被清零;注意调用 create_test_thread() 和 destroy_test_thread() 时,必须以 &g_ExistFlag (即它的地址)传入,以保证 g_ExistFlag 在函数中真的被修改了。