`

如何让errno多线程/进程安全

阅读更多

linux 或者 unix 环境中, errno 是一个十分重要的部分。在调用的函 数出现问题的时候,我们可以通过 errno 的值来确定出错的原因,这就会 涉及到一个问题,那就是如何保证 errno 在多线程或者进程中安全?我们希望在多线程或者进程中,每个线程或者进程都拥有自己独立和唯一的一个 errno ,这样就能够保证不会有竞争条 件的出现。一般而言,编译器会自动保证 errno 的安全性,但是为了妥善期间,我们希望在写 makefile 的时 候把 _LIBC_REENTRANT 宏定义,比 如我们在检查 <bits/errno.h> 文件中发现如下的定义:

 

# ifndef __ASSEMBLER__
/* Function to get address of global `errno' variable.  */
extern int *__errno_location (void) __THROW __attribute__ ((__const__));

#  if !defined _LIBC || defined _LIBC_REENTRANT
/* When using threads, errno is a per-thread value.  */
#   define errno (*__errno_location ())
#  endif
# endif /* !__ASSEMBLER__ */
#endif /* _ERRNO_H */

 

也就是说,在没有定义 __LIBC 或者定义 _LIBC_REENTRANT 的时候, errno 是多线程 / 进程安全的。
一般而言, __ASSEMBLER__, _LIBC _LIBC_REENTRANT 都不会被编译器定义,但是如果我们定义 _LIBC_REENTRANT 一次又何妨那?
为了检测一下你编译器是否定义上述变量,不妨使用下面一个简单程序。

 

#include <stdio.h>
#include <errno.h>

int main( void )
{
#ifndef __ASSEMBLER__
        printf( "Undefine __ASSEMBLER__\n" );
#else
        printf( "define __ASSEMBLER__\n" );
#endif

#ifndef __LIBC
        printf( "Undefine __LIBC\n" );
#else
        printf( "define __LIBC\n" );
#endif

#ifndef _LIBC_REENTRANT
        printf( "Undefine _LIBC_REENTRANT\n" );
#else
        printf( "define _LIBC_REENTRANT\n" );
#endif

        return 0;
}

 

希望读者在进行移植的时候,读一下相关的 unix 版本的 <bits/errno.h> 文 件,来确定应该定义什么宏。不同的 unix 版本可能存在着一些小的差别!

 

Quote : http://blog.csdn.net/hello_wyq/archive/2006/08/01/1006216.aspx

分享到:
评论

相关推荐

    树莓派4B使用 Adafruit_PCA9685 报错IOError: [Errno 121] Remote I/O error解决办法

    树莓派4B使用 Adafruit_PCA9685 报错IOError: [Errno 121] Remote I/O error解决办法 首先,确保已经下载了python2或python3的Adafruit_PCA9685库,然后要明白,报该错原因是:Adafruit_PCA9685无法找到外部的硬件,...

    一个进程池的服务器程序

    总的来说,思想是让子进程accept并处理请求,父进程通过子进程发来的信息控制请求数与子进程数之间的关系。 代码如下: 代码如下: #include #include &lt;sys/types.h&gt; #include &lt;sys/socket.h&gt; #include &lt;arpa/...

    linux_errno错误码

    linux错误码 errno值 #define EPERM 1/* Not super-user */ #define ENOENT 2 /* No such file or directory */ #define ESRCH 3/* No such process */ #define EINTR 4/* Interrupted system call */ #...

    linux下c语言的多线程编程

    我们在写linux的服务的时候,经常会用到linux的多线程...多线程的进程可以尽可能的利用系统CPU资源。 1创建线程 先上一段在一个进程中创建一个线程的简单的代码,然后慢慢深入。 #include #include #include&lt;stdl

    C语言头文件 ERRNO

    C语言头文件 ERRNOC语言头文件 ERRNOC语言头文件 ERRNOC语言头文件 ERRNOC语言头文件 ERRNOC语言头文件 ERRNOC语言头文件 ERRNOC语言头文件 ERRNOC语言头文件 ERRNOC语言头文件 ERRNOC语言头文件 ERRNOC语言头文件 ...

    第3章_linux多线程编程

    2、线程包含了表示进程内执行环境必须的信息,包括线程ID、一组寄存器、栈、调度优先级、策略、信号屏蔽字、errno变量、线程私有数据。 3、测试是否支持POSIX线程: 使用编译测试宏_POSIX_THREADS 调用sysconf,运行...

    Posix多线程程序设计源码

    Posix多线程程序设计书中实例源码。 头文件errors.h #ifndef __errors_h #define __errors_h #include #include &lt;errno.h&gt; #include #include #include /* * Define a macro that can be used for diagnostic...

    EAAGAIN errno11

    EAAGAIN errno11EAAGAIN errno11EAAGAIN errno11EAAGAIN errno11EAAGAIN errno11EAAGAIN errno11EAAGAIN errno11EAAGAIN errno11EAAGAIN errno11

    linux系统编程之线程.zip

    如果任意一个线程调用了exit或_exit,则整个进程的所有线程都终止,由于从main函数return也相当于调用exit,为了防止新创建的线程还没有得到执行就终止,我们在main函数return之前延时1秒,这只是一种权宜之计,即使...

    errno详解.txt

    解释linux系统errno的值,如果你不明白errno对应的错误信息,这篇文档将帮助你

    进程通信.doc

    B、共享数据:多个进程想要操作共享数据,一个进程对共享数据的修改,别的进程应该立刻看到。 C、通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)...

    errno(3) - Linux manual page.pdf

    当linux系统函数出错时,通常会返回一个负值,而且整型变量errno通常被设置为具有特定信息的值。例如,open 函数如果成功执行 则返回一个非负文件描述符,如出错则返回−1。在 open出错时,有大约15种不同的errno值(文件...

    linux基于多进程的socket通信

    #include &lt;errno.h&gt; #include "../comm/my_recv.h" // 自定义的头文件 #include "../comm/my_recv.c" #define SERVER_IP "127.0.0.1" #define SERV_PORT 6666 // 服务器端的端口 #define LISTENQ 12 // 连接请求...

    Python提示[Errno 32]Broken pipe导致线程crash错误解决方法

    本文实例讲述了Python提示[Errno 32]Broken pipe导致线程crash错误解决方法。分享给大家供大家参考。具体方法如下: 1. 错误现象 ThreadingHTTPServer 实现的 http 服务,如果客户端在服务器返回前,主动断开连接,...

    C头文件 errno.h

    errno.h 是C语言C标准函式库里的标头档,定义了通过错误码来回报错误资讯的宏.

    Linux系统调用出错errno描述一览

    Linux系统调用出错errno描述一览

    wallproxy Errno 10054

    wallproxy Errno 10054 解决方法

    Errno 14 curl#37 - "Couldn't open file /mnt/repodata/repomd.xml

    yum报错处理,引入文件到缺失目录下即可

    FileExistsError: [Errno 17] File exists: ‘/data1/XXX/val_processed/ct/’

    这个做记录主要想说python真的好智障! 错误原因就是: 代码中用os.mkdir()新建路径的话,该路径若已存在,便会报这个错误。...参考:https://stackoverflow.com/questions/46149537/python-errno-17-file-

    Linux中errno使用.docx

    Linux中errno使用.docx

Global site tag (gtag.js) - Google Analytics