我需要知道某个线程是否已经终止(如果不是,我必须等待它)
如果我在终止线程上调用pthread_join()
,它总是在我的glibc版本中返回成功。
但是pthread_join()
的文档说如果线程已经终止,它必须返回代码ESRCH
的错误
如果我致电pthread_kill(thread_id, 0)
,则会返回错误代码ESRCH
(正如预期的那样)
在glibc内部的源代码中,我看到pthread_join()
内部有一个简单的有效thread_id检查,但不检查线程是否存在。
在pthread_kill()
里面有真正的检查(在某些内核的列表中)。
有我的测试程序:
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
void * thread_func(void *arg)
{
printf("Hello! I`m thread_func!\nGood-bye!\n");
return NULL;
}
int main(void)
{
int res;
pthread_t thread_id;
printf("Hello from main()!\n");
pthread_create(&thread_id, NULL, thread_func, NULL);
printf("Waiting...\n");
sleep(3);
res = pthread_join(thread_id, NULL);
printf("pthread_join() returned %d (%s)\n", res, strerror(res));
res = pthread_kill(thread_id, 0);
printf("pthread_kill() returned %d (%s)\n", res, strerror(res));
return 0;
}
它是输出:
Hello! Waiting... Hello! I`m thread_func! Good-bye! pthread_join() returned 0 (Success) pthread_kill() returned 3 (No such process)
我的问题:使用pthread_join()来检查已终止的线程是否安全,或者我必须始终使用pthread_kill()?
答案 0 :(得分:3)
当一个线程退出时,它的代码会停止运行但它的&#34;尸体&#34;留在四周,以便父母收集返回代码。(1)
所以,即使你认为线程完全消失了,但事实并非如此。
对pthread_join
的调用将检查所述尸体的返回码,以便向父母通知事情的结果。 在收集完毕后,线程可以真正地休息。(2)
为什么pthread_join()
返回成功代码而pthread_kill
不是 - 你不允许杀死一个&#39;已经死了,但你 允许加入一个死了但仍然温暖的人: - )
您可以通过尝试以下代码来获得更好的教育,这些代码尝试加入线程两次:
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
void * thread_func(void *arg) {
printf("Hello! I`m thread_func!\nGood-bye!\n");
return NULL;
}
int main(void) {
int res;
pthread_t thread_id;
printf("Hello from main()!\n");
pthread_create(&thread_id, NULL, thread_func, NULL);
printf("Waiting...\n");
sleep(3);
res = pthread_join(thread_id, NULL);
printf("pthread_join() returned %d (%s)\n", res, strerror(errno));
res = pthread_join(thread_id, NULL);
printf("pthread_join() returned %d (%s)\n", res, strerror(errno));
return 0;
}
在我的系统上,我看到了:
Hello from main()!
Waiting...
Hello! I`m thread_func!
Good-bye!
pthread_join() returned 0 (No error)
pthread_join() returned 3 (No error)
换句话说,虽然线程已经死亡,但第一个pthread_join()
仍在工作。
(1)如果您愿意,您可以pthread_detach
一个线程,以便在终止时立即释放其资源。这将是:
pthread_create(&thread_id, NULL, thread_func, NULL);
pthread_detach(thread_id);
但我非常肯定,即使线程仍然存在,连接也会失败。
要查看线程是否仍在运行无论是否已分离,您只需使用:
if (pthread_kill(thread_id, 0) != 0)
// Thread is gone.
(2)对于这个答案的病态语气道歉,我今天感觉有点黑暗: - )
答案 1 :(得分:1)
pthread_join结束了线程对资源的使用。当线程到达终点并准备好进行清理时,它返回0。线程不会消失&#39;所有这一切都是默认的。
归零意味着:
1. the thread got cleaned up
2. the thread WAS still there waiting
所以不,不要使用pthread_kill,你有一个错误的主要假设:线程,除非设置为不可连接,否则在线程返回时不退出并清理堆栈和内存资源。换句话说,在您的示例中,return NULL
不会终止该线程。 pthread_join做了。
所以,是的,使用pthread_join等待线程完成。