gpt4 book ai didi

c - PTHREAD_CANCELED 和线程的启动函数返回值有什么问题

转载 作者:行者123 更新时间:2023-12-01 14:41:52 26 4
gpt4 key购买 nike

我正在阅读 Kerrisk's book并看到以下内容作为注释,

Caution is required when using a cast integer as the return value of a thread’s start function. The reason for this is that PTHREAD_CANCELED, the value returned when a thread is canceled (see Chapter 32), is usually some implementation-defined integer value cast to void *. If a thread’s start function returns the same integer value, then, to another thread that is doing a pthread_join(), it will wrongly appear that the thread was canceled. In an application that employs thread cancellation and chooses to return cast integer values from a thread’s start functions, we must ensure that a normally terminating thread does not return an integer whose value matches PTHREAD_CANCELED on that Pthreads implementation. A portable application would need to ensure that normally terminating threads don’t return integer values that match PTHREAD_CANCELED on any of the implementations on which the application is to run.

我不明白笔记的重要性。你能把它编码(显示它的简单代码片段)只是为了说明吗?这些案例中的问题是什么?

最佳答案

这是 PTHREAD_CANCELED 的典型定义(逐字引用自 /usr/include/pthread.h 在我输入此内容的机器上,它运行带有 GNU libc 的 Linux):

#define PTHREAD_CANCELED ((void *) -1)

因此,如果您有这样的代码来检查取消:

void *thread_result;
int rv = pthread_join(child, &thread_result);
if (rv)
error_exit("pthread_join failed", rv);
if (thread_result == PTHREAD_CANCELED)
error_exit("thread canceled", 0);

你不能也有这样的线程过程:

static void *appears_to_be_canceled(void *unused)
{
return ((void *) -1);
}

因为PTHREAD_CANCELED((void *) -1)是平等的。请注意,该数字不能保证为 -1,它可能因系统而异,并且没有好的方法可以在编译时找出它是什么,因为 ((void *)...)#if 中不可用表达。

有两种很好的方法可以避免这个问题:

  • 不要使用线程取消,所以你不必检查 PTHREAD_CANCELED并且不必关心它的数值是多少。由于其他几个原因,这是一个好主意,最重要的是取消使得编写健壮的多线程代码比现在更难。
  • 仅从您的线程过程中返回有效的指针,而不是数字。一个好的习语是这样的:

    struct worker_data
    {
    // put _everything_ your thread needs to access in here
    };
    static void *worker_proc (void *data_)
    {
    struct worker_data *data = data_;
    // do stuff with `data` here
    return data_;
    }

    返回 worker_data object 表示调用 pthread_join 的代码不必跟踪哪个 worker_data pthread_t对应的对象.这也意味着成功完成的线程的返回值保证不等于PTHREAD_CANCELED。 ,因为 PTHREAD_CANCELED保证不会与任何有效指针进行比较。

关于c - PTHREAD_CANCELED 和线程的启动函数返回值有什么问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54335311/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com