从 main 调用 pthread_exit 可以吗?

发布于 2024-09-16 00:04:39 字数 864 浏览 5 评论 0原文

当我从 main 调用 pthread_exit 时,程序永远不会终止。我希望程序能够完成,因为我正在退出程序的唯一线程,但它不起作用。看来挂了

#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.2pthreads-win32 v2.8.0.0 (链接到 libpthreadGC2.a)。

该库似乎没问题(例如,从 main 调用 pthread_selfpthread_create 工作正常)。

有什么原因导致我不应该从 main 调用 pthread_exit 吗?

When I call pthread_exit from main, the program never gets to terminate. I expected the program to finish, since I was exiting the program's only thread, but it doesn't work. It seems hung.

#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 shows that the (only) thread is in Wait:DelayExecution state.

According to pthread_exit documentation:

The process shall exit with an exit
status of 0 after the last thread has
been terminated. The behavior shall be
as if the implementation called
exit() with a zero argument at thread
termination time.

I'm using Dev-C++ v4.9.9.2 and pthreads-win32 v2.8.0.0 (linking against libpthreadGC2.a).

The library seems to be OK (for example, calling pthread_self or pthread_create from main works fine).

Is there any reason for what I'm not supposed to call pthread_exit from main?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我为君王 2024-09-23 00:04:39

那么它在 Linux 的 pthread 实现中绝对是合法的,请参阅 pthreads_exit。它指出

为了让其他线程继续执行,主线程应该终止
通过调用 pthread_exit() 而不是 exit(3)。

另外,看一下源代码 这里(torwads the end)显示它大致翻译为 _endthread 或 _endthreadex。 此处的文档没有提及在初始线程中调用它。

Well its definately legal in the linux implementation of pthreads, see the notes section in pthreads_exit. It states

To allow other threads to continue execution, the main thread should terminate
by calling pthread_exit() rather than exit(3).

Further, a look at the source code here (torwads the end) shows that it roughly translates to _endthread or _endthreadex. The documentation here for those makes no mention of not calling it in the initial thread.

灵芸 2024-09-23 00:04:39

这是完全合法且有意的行为。仅当所有线程终止或显式或隐式调用 exit 时,整个过程才会结束。

main 正常返回相当于调用 exit。如果您以 pthread_exit 结束 main,则明确表示您希望其他线程继续。

This completely legal and intended behavior. The whole process only ends when either all threads terminate or exit is called explicitly or implicitly.

A normal return from main is equivalent to a call to exit. If you end main with pthread_exit your are saying explicitly that you want the other threads to continue.

无风消散 2024-09-23 00:04:39

在main中使用pthread_exit就可以了。当使用 pthread_exit 时,主线程将停止执行并保持僵尸(已失效)状态,直到所有其他线程退出。

如果您在主线程中使用 pthread_exit,则无法获取其他线程的返回状态,也无法对其他线程进行清理(可以使用 pthread_join(3) 完成)。另外,最好分离线程(pthread_detach(3)),以便在线程终止时自动释放线程资源。直到所有线程退出后,共享资源才会被释放。

在主线程不分配资源时使用就可以,不需要清理。下面的代码显示了在主线程中使用 pthread_exit 。 main 中的第二个 printf 不会被打印,因为主线程在调用 pthread_exit 后退出。 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了解更多有关线程的信息。

It's fine to use pthread_exit in main. When pthread_exit is used, the main thread will stop executing and will remain in zombie(defunct) status until all other threads exit.

If you are using pthread_exit in main thread, cannot get return status of other threads and cannot do clean-up for other threads (could be done using pthread_join(3)). Also, it's better to detach threads(pthread_detach(3)) so that thread resources are automatically released on thread termination. The shared resources will not be released until all threads exit.

Its ok to use when not allocating resources in the main thread, clean-up is not needed. Below code shows using pthread_exit in the main thread. The second printf in main is not printed as main thread exits after calling pthread_exit. Ps output shows the defunct main thread.

#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());
}

Output of the above code:

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 output:

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`

Please check blog Tech Easy for more information on threads.

神仙妹妹 2024-09-23 00:04:39

在Linux(CentOS Linux版本7.2.1511(Core))上测试时,我发现主程序确实等待“子”线程继续。
另外,我无法从 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

When testing on Linux (CentOS Linux release 7.2.1511 (Core)) I found that indeed the main program waits for "child" threads to continue.
Also I was not able to pass out a return code from main, although it can be specified as argument for pthread_exit(), as Raul said above it always returns with exit code 0:

retval=3;
pthread_exit(&retval);

We also observed an error message when using Clang compiler (version 3.4.2) and sanitizer options:

==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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文