当我从pthread_exit
拨打main
时,程序永远不会终止。我期望程序完成,因为我退出程序的唯一线程,但它不起作用。它好像挂了。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int main(int argc, char *argv[])
{
printf("-one-\n");
pthread_exit(NULL);
printf("-two-\n");
}
Process Explorer 显示(仅)线程处于Wait:DelayExecution
状态。
根据pthread_exit
文件:
该过程应以退出方式退出 最后一个线程之后的状态为0 被终止了。行为应该是 好像是实现调用 在线程处使用零参数的exit() 终止时间。
我正在使用 Dev-C ++ v4.9.9.2 和 pthreads-win32 v2.8.0.0 (链接libpthreadGC2.a
)。
库似乎没问题(例如,从pthread_self
调用pthread_create
或main
可以正常工作。
我是否应该从pthread_exit
拨打main
来解决问题?
答案 0 :(得分:16)
它在pthreads的linux实现中绝对合法,请参阅pthreads_exit中的注释部分。它声明
要允许其他线程继续执行,主线程应该终止 通过调用pthread_exit()而不是exit(3)。
此外,查看源代码here(转发结尾)显示它大致转换为_endthread或_endthreadex。文档here没有提及在初始线程中没有调用它。
答案 1 :(得分:15)
这完全合法且有意的行为。整个过程仅在所有线程终止或显式或隐式调用exit
时结束。
main
的正常回报相当于对exit
的回复。如果您使用main
结束pthread_exit
,则明确表示您希望其他主题继续。
答案 2 :(得分:3)
在main中使用pthread_exit很好。使用pthread_exit时,主线程将停止执行,并将保持僵尸(已取消状态)状态,直到所有其他线程退出。
如果在主线程中使用pthread_exit,则无法获取其他线程的返回状态,也无法对其他线程进行清理(可以使用pthread_join(3)完成)。另外,最好分离线程(pthread_detach(3)),以便在线程终止时自动释放线程资源。在所有线程退出之前,不会释放共享资源。
在主线程中不分配资源时也可以使用,不需要清理。下面的代码显示在主线程中使用pthread_exit。由于调用pthread_exit后主线程退出,因此不会打印main中的第二个printf。 Ps输出显示已失效的主线程。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
void *functionC(void *);
int main()
{
int rc;
pthread_t th;
if(rc = pthread_create(&th, NULL, &functionC, NULL))
{
printf("Thread creation failed, return code %d, errno %d", rc, errno);
}
printf("Main thread %lu: Sleeping for 20 seconds\n", pthread_self());
fflush(stdout);
sleep(20);
pthread_exit(NULL);
printf("Main thread %lu: This will not be printed as we already called pthread_exit\n", pthread_self());
exit(0);
}
void *functionC(void *)
{
printf("Thread %lu: Sleeping for 20 second\n", pthread_self());
sleep(20);
printf("Thread %lu: Came out of first and sleeping again\n", pthread_self());
sleep(20);
printf("CThread %lu: Came out of second sleep\n", pthread_self());
}
以上代码的输出:
Main thread 140166909204288: Sleeping for 20 seconds
Thread 140166900684544: Sleeping for 20 second
Thread 140166900684544: Came out of first and sleeping again
CThread 140166900684544: Came out of second sleep
ps
输出:
root@xxxx-VirtualBox:~/pthread_tst# ps -elfT |grep a.out
0 S root 9530 9530 9496 0 80 0 - 3722 hrtime 17:31 pts/1 00:00:00 ./a.out
1 S root 9530 9531 9496 0 80 0 - 3722 hrtime 17:31 pts/1 00:00:00 ./a.out
0 S root 9537 9537 2182 0 80 0 - 5384 pipe_w 17:31 pts/0 00:00:00 grep --color=auto a.out
root@xxxx-VirtualBox:~/pthread_tst# ps -elfT |grep a.out
0 Z root 9530 9530 9496 0 80 0 - 0 - 17:31 pts/1 00:00:00 [a.out] <defunct>
1 S root 9530 9531 9496 0 80 0 - 4258 hrtime 17:31 pts/1 00:00:00 ./a.out
0 S root 9539 9539 2182 0 80 0 - 5384 pipe_w 17:31 pts/0 00:00:00 grep --color=auto a.out`
请查看博客Tech Easy,以获取有关线程的更多信息。
答案 3 :(得分:1)
在Linux上测试时(CentOS Linux版本7.2.1511(核心版))我发现主程序确实等待了#34; child&#34;线程继续。 此外,我无法从main传递返回代码,虽然它可以指定为pthread_exit()的参数,因为Raul上面说它总是以退出代码0返回:
retval=3;
pthread_exit(&retval);
使用Clang编译器(版本3.4.2)和清洁剂选项时,我们也发现了一条错误消息:
==5811==ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed: 0x7f4c090321d0 in thread T0
#0 0x7f4c08be3e29 in __interceptor_free (/home/karstenburger/tests/libc/pthread_exit_in_main/a+0x65e29)
#1 0x7f4c08333358 in free_key_mem (/lib64/libdl.so.2+0x1358)
#2 0x7f4c08745bc1 in __nptl_deallocate_tsd (/lib64/libpthread.so.0+0x7bc1)
#3 0x7f4c07771b38 in __libc_start_main (/lib64/libc.so.6+0x21b38)
#4 0x7f4c08bfa08c in _start (/home/karstenburger/tests/libc/pthread_exit_in_main/a+0x7c08c)
AddressSanitizer can not describe address in more detail (wild memory access suspected).
SUMMARY: AddressSanitizer: bad-free ??:0 __interceptor_free
==5811==ABORTING