【问题标题】:What happens if pthread_key_delete is called on a key after a failed pthread_key_create?如果在 pthread_key_create 失败后对密钥调用 pthread_key_delete 会发生什么?
【发布时间】:2013-08-05 18:02:57
【问题描述】:

假设如下代码:

pthread_key_t key;
pthread_key_create(&key, NULL);    /* failure here */
pthread_key_delete(key);

如果pthread_key_create 失败,对pthread_key_delete 的调用是否被视为未定义行为?如果pthread_key_create被注释掉怎么办?

POSIX 标准的pthread_key_delete 部分指出:

pthread_key_delete() 函数将删除先前由 pthread_key_create() 返回的特定于线程的数据键。

由于pthread_key_delete 期望pthread_key_create 之前返回的特定于线程的数据键,恐怕在pthread_key_create 未返回的键上调用pthread_key_delete 会导致未定义的行为。

【问题讨论】:

    标签: pthreads posix pthread-key-create


    【解决方案1】:

    是的,在您链接的标准没有定义该用例中发生的情况的范围内,它是隐含的未定义行为。

    然而,SUSv7在其对pthread_key_delete 的讨论中明确表示,在其CHANGE HISTORY for Issue 7 中明确表示:

    删除了未从 pthread_key_create() 获取的键值或使用 pthread_key_delete() 删除的键的 [EINVAL] 错误;这种情况会导致未定义的行为。

    【讨论】:

    • 天哪,我刚刚意识到我阅读了较旧的 Issue 6,而我原本打算阅读更新的 Issue 7。下次我一定要留意。
    • @VilhelmGray,很公平。我认为这两者都是相同的未定义行为,只是 SUSv7 对此更加明确。
    • 是的,我相信这可能是决定明确声明在这种情况下存在未定义行为的决定。
    【解决方案2】:

    通过查看pthread_key_createpthread_key_delete的源代码 似乎 pthread_key_create 正在返回一个内存位置并填充“key”结构的其他字段,这与 posix 中的其他所有内容一样是不透明的。

    pthread_key_delete 期望使用有效数据填充/设置关键结构字段以搜索内存位置。因此,在 pthread_key_create 失败后调用 pthread_key_delete 似乎会导致未定义的行为。这是另一个似乎得到意见支持的链接。

    How does pthread_key_t and the method pthread_key_create work?

    我希望这会有所帮助。

    【讨论】:

    • 您选择作为示例的源代码库在使用方面可能不是最广泛使用的 Pthread 实现,不是吗?
    • 另外,pthread_key_delete() 链接的代码不完全符合 POSIX 规范。例如,如果传入了清零的pthread_key_t 密钥,或者没有找到密钥,它将不会返回EINVAL
    • 您可以在下面看到 pthread_key_delete.c code.mjdsystems.ca/p/equalizer/source/tree/…sourceware.org/pub/pthreads-win32/sources/… 的另外两个示例,它们都没有返回 EINVAL。但是,有些实现确实会返回 EINVAL。例如:cristi.indefero.net/p/uClibc-cristi/source/tree/… 所以,这证明行为是“未定义的”。
    • 对于eglibc,将定义行为并返回EINVAL。没有钥匙会激怒UB。但是,我确实同意在未定义的键上调用 pthread_key_delete() 是一个坏主意,尽管标准(如我的回答所链接)没有明确提到这一点。
    • 我对查看任何实现以确定使用是否为未定义行为的适当性持怀疑态度。行为是否未定义与行为规范有关,与它们的特定实现无关。
    猜你喜欢
    • 2011-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-18
    • 1970-01-01
    • 1970-01-01
    • 2018-10-07
    相关资源
    最近更新 更多