在 pthread_create 和 pthread_detach 之后立即取消 pthread_cancel 时出现未知故障

问题描述 投票:0回答:2

我测试了线程取消过程,并有这样的代码。 它在我的 ARM 机器上工作,有时工作正常,有时导致段错误,有时创建后卡住。

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>

void *t(void *ptr)
{
    printf("in t\n");
    sleep(0.3);
    return NULL;
}

int main() {

    pthread_t p;
    pthread_create(&p, NULL, t, NULL);
    printf("created\n");
    pthread_detach(p);
    pthread_cancel(p);
    printf("canceled\n");

    return 0;
}

不知道哪个部分导致了问题(卡住/段错误)。

c pthreads
2个回答
3
投票

18年前回答过同样的问题。在分离的线程上调用

pthread_cancel
是不安全的。

您的代码存在竞争条件,因此其行为未定义。如果线程在您调用

pthread_cancel
之前设法终止,则您正在向
pthread_cancel
传递无效参数,这是未定义的行为。

如果

main
中的代码正在管理线程的生命周期,请不要分离它,否则无法确保线程ID保持有效。如果
main
中的代码不管理线程的生命周期,请勿在其中调用
pthread_cancel
。您永远找不到安全的方法来平分差额。

您应该将

pthread_detach
视为使线程 ID 无效(或用 Glenn Burkhardt 的话说“语义上关闭”),并且不要再次使用它。

正如一些程序员家伙指出的那样,你的

sleep
四舍五入为零,这使得更有可能遇到竞争条件。


0
投票

确保:

pthread_cancel(p);

之前被调用:

pthread_detach(p);

你会没事的。更多细节,为什么它有效,可以在这个答案中找到:Is it safe to call pthread_cancel() on returned thread?

通常,在调用

pthread_join()
pthread_detach()
后,不得再使用线程标识符。

© www.soinside.com 2019 - 2024. All rights reserved.