多线程实现中的错误

时间:2013-07-12 09:49:47

标签: c++ c errno

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

3 个答案:

答案 0 :(得分:3)

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");
}

答案 1 :(得分:3)

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

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

例如,GNU C库定义了与

类似的东西
#define errno (*(__errno_location()))

其中__errno_location()是一个内联函数,用于计算线程本地errno的地址。

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

答案 2 :(得分:0)

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

通过使用以下内容可以轻松实现此目的:

int __thread errno;

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

作为errno的用户,您无需担心这一点。你甚至不必担心errno可能已经被另一个线程先发制人地改变了。