一、errno的由来
     在C编程中,errno是个不可缺少的变量,特别是在网络编程中。如果你没有用过errno,那只能说明你的程序不够健壮。当然,如果你是WIN32平台的GetLastError(),效果也是一样的。
     为什么会使用errno呢?个人认为,这是系统库设计中的一个无奈之举,他更多的是个技巧,而不是架构上的需要。我们观察下函数结构,可以发现,函数的参数返回值只有一个,这个返回值一般可以携带错误信息,比如负数表示错误,而正数表述正确的返回值,比如recv函数。但是对于一些返回指针的函数,如: char *get_str();这个方法显然没有用的。NULL可以表示发生错误,但是发生什么错误却毫无办法。于是,errno就诞生了。全局变量errno可以存放错误原因,当错误发生时,函数的返回值是可以通过非法值来提示错误的发生。

二、errno的线程安全
     errno是全局变量,但是在多线程环境下,就会变得很恐怖。当你调用一个函数时,发现这个函数发生了错误,但当你使用错误原因时,他却变成了另外一个线程的错误提示。想想就会觉得是件可怕的事情。
     将errno设置为线程局部变量是个不错的主意,事实上,GCC中就是这么干的。他保证了线程之间的错误原因不会互相串改,当你在一个线程中串行执行一系列过程,那么得到的errno仍然是正确的。
    看下,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__ */
     而errno.h中是这样定义的:
/* Declare the `errno' variable, unless it's defined as a macro by
   bits/errno.h.  This is the case in GNU, where it is a per-thread
   variable.  This redeclaration using the macro still works, but it
   will be a function declaration without a prototype and may trigger
   a -Wstrict-prototypes warning.  */
#ifndef errno
extern int errno;
#endif
     显然,errno实际上,并不是我们通常认为的是个整型数值,而是通过整型指针来获取值的。这个整型就是线程安全的。

三、errno的实现

static pthread_key_t key;
static pthread_once_t key_once = PTHREAD_ONCE_INIT;
static void make_key()
{
    (void) pthread_key_create(&key, NULL);
}
int *_errno()
{
    int *ptr ;
    (void) pthread_once(&key_once, make_key);
    if ((ptr = pthread_getspecific(key)) == NULL) 
    {
        ptr = malloc(sizeof(int));        
        (void) pthread_setspecific(key, ptr);
    }
    return ptr ;
}

 四、errno的应用
    errno在库中得到广泛的应用,但是,错误编码实际上不止那么多。我们需要在自己的系统中增加更多的错误编码。一种方式就是直接利用errno,另外一种方式就是定义自己的user_errno。
   使用errno,strerror可能无法解析,这需要自己解决。但errno使用线程变量的方式值得借鉴。

errno多线程安全(转载)的更多相关文章

  1. Java多线程学习(转载)

    Java多线程学习(转载) 时间:2015-03-14 13:53:14      阅读:137413      评论:4      收藏:3      [点我收藏+] 转载 :http://blog ...

  2. VC++6.0 下配置 pthread库2010年12月12日 星期日 13:14VC下的pthread多线程编程 转载

    VC++6.0 下配置 pthread库2010年12月12日 星期日 13:14VC下的pthread多线程编程     转载 #include <stdio.h>#include &l ...

  3. java创建多线程(转载)

    转载自:Java创建线程的两个方法 Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对 ...

  4. 使用总结:java多线程总结 <转载>

    转载 https://www.cnblogs.com/rollenholt/archive/2011/08/28/2156357.html java多线程总结 2011-08-28 20:08  Ro ...

  5. JAVA多线程 问题 转载

    参考:http://ifeve.com/java-multi-threading-concurrency-interview-questions-with-answers/ http://www.cn ...

  6. C# 中的多线程(转载)

    关于多线程的系列,翻译自国外大牛的文章,值得推荐 原文地址:https://blog.gkarch.com/topic/threading.html

  7. 基于事件的 NIO 多线程服务器--转载

    JDK1.4 的 NIO 有效解决了原有流式 IO 存在的线程开销的问题,在 NIO 中使用多线程,主要目的已不是为了应对每个客户端请求而分配独立的服务线程,而是通过多线程充分使用用多个 CPU 的处 ...

  8. ArcGIS Engine 中的多线程使用[转载]

    一直都想写写AE中多线程的使用,但一直苦于没有时间,终于在中秋假期闲了下来.呵呵,闲话不说了,进入正题!         大家都了解到ArcGIS中处理大数据量时速度是相当的慢,这时如果你的程序是单线 ...

  9. 详解iOS多线程 (转载)

    iPhone 中的线程应用并不是无节制的,官方给出的资料显示iPhone OS下的主线程的堆栈大小是1M,第二个线程开始都是512KB.并且该值不能通过编译器开关或线程API函数来更改. 只有主线程有 ...

随机推荐

  1. JavaScript高级程序设计(第三版)第三章 基本概念

    3.3 变量 在使用var声明但未对其加以初始化时,这个变量的值就是undefinded. var message; //这个变量声明之后默认取得了undefinded值 //下面这个变量并没有声明 ...

  2. 《学习OpenCV》练习题第四章第一题b&c

    #include <highgui.h> #include <cv.h> #pragma comment (lib,"opencv_calib3d231d.lib&q ...

  3. 轻松学习Linux之认识Shell

            Shell是一个命令解释器提供了用户与内核进行交互操作的一种接口shell,编程对於系统管理员或是一般使用者都相当有用,除了自动化,还可写出一些有趣的小工具,Linux本身有各种版本一 ...

  4. Orion Network Performance Monitor 软件在网络管理中的应用

    Orion Network Performance Monitor 软件在网络管理中的应用       Orion Network Performance Monitor是完全的带宽性能和故障管理软件 ...

  5. SQL Server 系统视图

    SQL Server系统视图非常的多,因此不可能一个一个地写,我最近一直在想,对于数据库的系统视图应该如何学,但是看了一下目录之后,我呆了,我觉得每个写一次,可能都要花费1个星期的时间,如果对每一个返 ...

  6. js冲突

    bundles.Add(new ScriptBundle("~/bundles/jquery").Include(//"~/Scripts/modernizr-2.6.2 ...

  7. Android SDK Manager更新不了的解决办法

    android SDK Manager更新不了,出现错误提示:"Failed to fetch URL..."! 可以用以下办法解决: 使用SDK Manager更新时出现问题 F ...

  8. HDU2838Cow Sorting(树状数组)

    题目意思是说给你一列数,每次可以将相邻的两个数交换,这一步的代价是这两个数的和,求将所有数排好序的最少代价. 题解: 我们可以这么思考,由于每次都是交换相邻的两个数,所以将一个数放到它自己的位置去后, ...

  9. 一个人写的操作系统 - Sparrow OS

    一个人写的操作系统 - Sparrow OS 自己写一个操作系统,这是在过去的几年里我一直为之努力的目标,现在终于完成了. 缘起 自己动手写操作系统的动机最初来自于学习Linux遇到的困难. 我是一个 ...

  10. UI:tomcat(说话小程序)、相框动画、UISgmentcontrol、UISwitch

    UISegmentedControl 分段控件 //1. UISegmentedControl 分段控件 (就是一个一个的按钮) //分段显示的标题是以一个数组存储的 NSArray * titles ...