多线程实现中的errno

errno in Multithread implementation

本文关键字:errno 实现 多线程      更新时间:2023-10-16

要在多线程应用程序中使用errno,请参阅http://www.cplusplus.com/reference/cerrno/errno/指示它应该在每个线程中本地实现。这是什么意思?

errno应为thread-local。在每个thread中,该变量的值可以不同。

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

errno实现为thread_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");
}

历史上,errnoint类型的常见变量,即每个模块都有自己的定义,链接器负责合并它们。因此,程序只是在全局范围内声明int errno;,并有一个有效的定义。

这在多线程环境中会崩溃,因为只有一个变量。因此,errno.h现在需要定义左值int,程序不应该定义自己的errno

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

#define errno (*(__errno_location()))

其中CCD_ 12是计算线程本地CCD_。

所有这些都与应用程序无关,只是定义自己的errno是一个错误。

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

该实现可以通过使用以下内容轻松实现:

int __thread errno;

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

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