zoukankan      html  css  js  c++  java
  • 从Linux的errno到Java的ThreadLocal


    在Linux下执行系统调用时,一般会有一个返回值表示成功或失败,但是这个值只说明了成功或失败,却没有说明是如何成功或失败的。

    errno就是为了解决这个问题的,系统调用会把错误号设置为errno,我们通过错误号就能知道失败的原因。还可以使用strerror打印出这个错误号对应的字符串说明。老版本的Linux需要加上extern int errno,现在直接引入<errno.h>就行了.

    errno示例:

    wKioL1WbuPjQ9_gzAAHrJFspGzI545.jpg

    现在的问题来了。假如我有两个线程,代码如下:

    wKiom1Wbt2CSHc8DAAC4FjSCW0c854.jpg

    errno是一个全局变量,那么假如执行顺序为 1-1,2-1,1-2,2-2,线程1打印出的errno就是线程2的,这就是errno的问题,线程不安全。

    但是测试很多次,结果都是正确的。虽然你用这个errno是当作一个全局变量的,但是实际上是个宏。用gcc -E将源代码的宏展开,可以看到,errno被替换成了一个函数。

    wKioL1WbuZuyhJVTAAJJJiKqJHo234.jpg

    使用man errno查看对errno的解释,可以看到下面一句话:

           errno  is  defined  by  the ISO C standard to be a modifiable lvalue of
           type int, and must not be explicitly declared; errno may  be  a  macro.
           errno  is  thread-local;  setting  it in one thread does not affect its
           value in any other thread.

    所以errno并不是一个全局变量,而是一个thread-local,每个线程都有一个。我们可以自己实现一个errno。

    自己写一个errno


    仅仅演示一下errno的基本原理,使用一个map存放各个线程的errno,而这个map的key就是threadId。系统调用执行完毕后,会将错误码写入此线程对应的errno中。代码中的系统调用是一个假系统调用,some_system_call()。

    实际开发中,对于开发者,他实际上是看不到set_errno(),get_errno()这些函数的,他只需要取errno就行了。

    wKiom1Wbudzhz-3IAAUruAEgEOY812.jpg

    Java的ThreadLocal


    Java的ThreadLocal和Linux的errno是一样的,只不过errno对开发者来说更简单一点,而且只能取,当作一个变量就行了。

    wKioL1WbvwTCsMG7AAI8sT9dyJo690.jpg

    只定义了一个ThreadLocal,但是各个线程里的都不一样。

    自己实现一个ThreadLocal


    其实ThreadLocal也和上面我自己实现的errno类似,用了一个Map,感兴趣的可以去看一下jdk源码,我写了一个很简陋的MyThreadLocal,Java的ThreadLocal的原理大致就是这样的。直接将上面的代码的ThreadLocal替换成MyThreadLocal就可以运行,当然这个MyThreadLocal太简单,仅仅为了介绍原理。

    wKioL1WbwHKxdsl-AAJ3jZYOBEA724.jpg

    https://www.jianshu.com/p/cdaf9b91fd21

    https://www.jianshu.com/p/38a85d1851bb

    https://www.jianshu.com/p/07ce7190a097

  • 相关阅读:
    BZOJ 1040 (ZJOI 2008) 骑士
    BZOJ 1037 (ZJOI 2008) 生日聚会
    ZJOI 2006 物流运输 bzoj1003
    ZJOI 2006 物流运输 bzoj1003
    NOI2001 炮兵阵地 洛谷2704
    NOI2001 炮兵阵地 洛谷2704
    JLOI 2013 卡牌游戏 bzoj3191
    JLOI 2013 卡牌游戏 bzoj3191
    Noip 2012 day2t1 同余方程
    bzoj 1191 [HNOI2006]超级英雄Hero——二分图匹配
  • 原文地址:https://www.cnblogs.com/awzh2020/p/12615464.html
Copyright © 2011-2022 走看看