3

要在多线程应用程序中使用 errno,此参考http://www.cplusplus.com/reference/cerrno/errno/表明它应该在每个线程中本地实现。这意味着什么?

4

3 回答 3

4

errno应该是thread-local。在这个变量的每个thread值可以是不同的。

它应该在每个线程中本地实现

实现errnothread_local变量不是您的职责。它适用于编译器开发人员。

来自cppreference.com

errno 是用于错误指示的预处理器宏。 它扩展为 int 类型的线程局部可修改左值。 (C++11 起)

简单来说,在 C++11 编译器中,这段代码永远不应该断言

#include <iostream>
#include <cerrno>
#include <thread>
#include <cassert>

int g_errno = 0;

void thread_function()
{
   errno = E2BIG;
   g_errno = errno;
}

int main()
{
   errno = EINVAL;
   std::thread thread(thread_function);
   thread.join();
   assert(errno != g_errno && "not multithreaded");
}
于 2013-07-12T09:54:24.290 回答
3

从历史上看,errno它是一个通用类型变量int——即每个模块都有自己的定义,链接器负责合并它们。所以程序简单地在int errno;全球范围内陈述并有一个工作定义。

这在多线程环境中会失效,因为只有一个变量。因此,errno.h现在需要定义一个lvalue int的东西,并且程序不应该定义自己的errno.

例如,GNU C 库定义了类似于

#define errno (*(__errno_location()))

where__errno_location()是一个计算线程本地地址的内联函数errno

所有这些都与应用程序无关,除非定义自己的errno.

于 2013-07-12T10:37:46.360 回答
0

这意味着每个线程都应该有自己的errno变量实例

该实现可以通过使用类似的东西轻松实现这一点:

int __thread errno;

__thread作为一个 gcc 扩展,确保变量是线程本地的(因此一个线程不能覆盖变量的另一个线程实例)

作为 errno 的用户,您无需担心这一点。您甚至不必担心 errno 可能已被另一个线程抢先更改。

于 2013-07-12T09:54:54.460 回答