导读

strerror是否线程安全了? 1

errno是否线程安全? 1

附1:strerror源码 2

附2:__strerror_r源码 2

strerror是否线程安全了?

答案是NO,但它有个线程安全的版本:strerror_r。借助Linux的man,即可看到详情:

#include <string.h>

char *strerror(int errnum);

int strerror_r(int errnum, char *buf, size_t buflen); /* GNU-specific */

那么,在多线程中使用strerror是否安全了?答案是不一定,一定情况下也是非常安全的。

不安全会造成内存违规访问吗?也就是会发生SIGSEGV吗?答案是NO,仍是内存安全的,但是可能会返回错乱的字符串。

那么,在多线程程序中,什么情况下使用strerror是绝对安全的了?如果参数errnum是一个已知的errno,则使用strerror是绝对安全的,也就是会返回期待的字符串,而不会出现乱码。

对比strerror源码,是因为strerror会在下述直接返回:

if (__builtin_expect (ret != NULL, 1))

return ret;

而这走的是_strerror_r中的分支:

return (char *) _(_sys_errlist_internal[errnum]);

errno是否线程安全?

答案是不一定,取决于编译宏:

#  if !defined _LIBC || defined _LIBC_REENTRANT

/* When using threads, errno is a per-thread value.  */

#   define errno (*__errno_location ())

#  endif

可以通过下段小代码,来确定默认时是否有定义,如果没有,则需要在编译时加上:

#include <stdio.h>

int main()

{

#ifdef _GNU_SOURCE

printf("_GNU_SOURCE defined\n");

#else

printf("_GNU_SOURCE not defined\n");

#endif

#ifdef _LIBC_REENTRANT

printf("_LIBC_REENTRANT defined\n");

#else

printf("_LIBC_REENTRANT not defined\n");

#endif

#ifdef _LIBC

printf("_LIBC defined\n");

#else

printf("_LIBC not defined\n");

#endif

return 0;

}

附1:strerror源码

// glibc-2.14\string\strerror.c

#include <errno.h>

/* Return a string describing the errno code in ERRNUM.

The storage is good only until the next call to strerror.

Writing to the storage causes undefined behavior.  */

libc_freeres_ptr (static char *buf);

char *

strerror (errnum)

int errnum;

{

char *ret = __strerror_r (errnum, NULL, 0);

int saved_errno;

if (__builtin_expect (ret != NULL, 1))

return ret;

saved_errno = errno;

if (buf == NULL)

buf = malloc (1024);

__set_errno (saved_errno);

if (buf == NULL)

return _("Unknown error");

return __strerror_r (errnum, buf, 1024);

}

附2:__strerror_r源码

// glibc-2.14\string\_strerror.c

/* Return a string describing the errno code in ERRNUM.  */

char *

__strerror_r (int errnum, char *buf, size_t buflen)

{

if (__builtin_expect (errnum <  || errnum >= _sys_nerr_internal

|| _sys_errlist_internal[errnum] == NULL, 0))

{

/* Buffer we use to print the number in.  For a maximum size for

`int' of 8 bytes we never need more than 20 digits.  */

char numbuf[21];

const char *unk = _("Unknown error ");

size_t unklen = strlen (unk);

char *p, *q;

bool negative = errnum < 0;

numbuf[20] = '\0';

p = _itoa_word (abs (errnum), &numbuf[20], 10, 0);

/* Now construct the result while taking care for the destination

buffer size.  */

q = __mempcpy (buf, unk, MIN (unklen, buflen));

if (negative && unklen < buflen)

{

*q++ = '-';

++unklen;

}

if (unklen < buflen)

memcpy (q, p, MIN ((size_t) (&numbuf[21] - p), buflen - unklen));

/* Terminate the string in any case.  */

if (buflen > 0)

buf[buflen - 1] = '\0';

return buf;

}

return (char *) _(_sys_errlist_internal[errnum]);

}

weak_alias (__strerror_r, strerror_r)

libc_hidden_def (__strerror_r)

strerror线程安全分析的更多相关文章

  1. Java线程问题分析定位

    Java线程问题分析定位 分析步骤: 1.使用top命令查看系统资源占用情况,发现Java进程占用大量CPU资源,PID为11572: 2.显示进程详细列表命令:ps -mp 11572 -o THR ...

  2. Android系统--输入系统(七)Reader_Dispatcher线程启动分析

    Android系统--输入系统(七)Reader_Dispatcher线程启动分析 1. Reader/Dispatcher的引入 对于输入系统来说,将会创建两个线程: Reader线程(读取事件) ...

  3. Android系统--输入系统(十三)Dispatcher线程情景分析_Reader线程传递事件

    Android系统--输入系统(十三)Dispatcher线程情景分析_Reader线程传递事件 1. 输入按键 我们知道Android系统的按键分为三类:(1)Global Key;(2)Syste ...

  4. Android系统--输入系统(十四)Dispatcher线程情景分析_dispatch前处理

    Android系统--输入系统(十四)Dispatcher线程情景分析_dispatch前处理 1. 回顾 我们知道Android输入系统是Reader线程通过驱动程序得到上报的输入事件,还要经过处理 ...

  5. Spring中获取request的几种方法,及其线程安全性分析

    前言 本文将介绍在Spring MVC开发的web系统中,获取request对象的几种方法,并讨论其线程安全性. 原创不易,如果觉得文章对你有帮助,欢迎点赞.评论.文章有疏漏之处,欢迎批评指正. 欢迎 ...

  6. 【转】java线上程序排错经验2 - 线程堆栈分析

    前言 在线上的程序中,我们可能经常会碰到程序卡死或者执行很慢的情况,这时候我们希望知道是代码哪里的问题,我们或许迫切希望得到代码运行到哪里了,是哪一步很慢,是否是进入了死循环,或者是否哪一段代码有问题 ...

  7. [No000016E]Spring 中获取 request 的几种方法,及其线程安全性分析

    前言 本文将介绍在Spring MVC开发的web系统中,获取request对象的几种方法,并讨论其线程安全性. 原创不易,如果觉得文章对你有帮助,欢迎点赞.评论.文章有疏漏之处,欢迎批评指正. 欢迎 ...

  8. java线程dump分析工具

    jstack和线程dump分析  java程序性能分析之thread dump和heap dump 一.[内存dump] jmap –dump:live,format=b,file=heap.bin ...

  9. Spring中获取request的几种方法,及其线程安全性分析(山东数漫江湖)

    前言 本文将介绍在Spring MVC开发的web系统中,获取request对象的几种方法,并讨论其线程安全性. 原创不易,如果觉得文章对你有帮助,欢迎点赞.评论.文章有疏漏之处,欢迎批评指正. 欢迎 ...

随机推荐

  1. (文件名.JAVA)的文件名只能与该文件中的public类的名称一致

    1.如果类Yuangong 被声明为公共的(public),那么必须将类Yuangong 保存在名为Yuangong.java的文件中:2.反之,在一个文件中最多包含一个顶级的公共类,并且该公共类的名 ...

  2. java之IO整理(下)

    一:对象的序列化 对象序列化就是把一个对象变为二进制数据流的一种方法. 一个类要想被序列化,就行必须实现java.io.Serializable接口.虽然这个接口中没有任何方法,就如同之前的clone ...

  3. PHP中的traits简单理解

    Traits可以理解为一组能被不同的类都能调用到的方法集合,但Traits不是类!不能被实例化.先来例子看下语法: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 ...

  4. C#命名规则和风格(收集)

    1.     文件命名组织 1-1文件命名 1.        文件名遵从Pascal命名法,无特殊情况,扩展名小写. 2.        使用统一而又通用的文件扩展名: C# 类 .cs 1-2文件 ...

  5. U3D中的又一个坑

    using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEngine; pu ...

  6. Linux命令详解1--文件和目录管理之文件查找和比较

    1. 文件查找 1.1 strings命令 ------- 在对象文件或二进制文件中查找可打印的字符串.字符串是4个或更多可打印的任意序列,以换行或空字符结束. strings命令对识别随机对象文件很 ...

  7. System.Web.Mvc.Html 命名空间小计

    1,Html.Action    使用指定参数调用指定子操作方法并以 HTML 字符串形式返回结果. 1 <div id="HtmlAction"> 2 3 @Html ...

  8. 二维码生成插件qrious及网站扫码登录的一些理解

    什么是二维码 ​ 二维码又称QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型. ...

  9. Struts2分模块开发

    -------------------siwuxie095 Struts2 分模块开发 在实际开发中,如果一个项目是团队开发的,也就是很多人开发的, 每个人都需要去修改 struts.xml,因为 s ...

  10. 五分钟带你入门TensorFlow

    TensorFlow是Google开源的一款人工智能学习系统.为什么叫这个名字呢?Tensor的意思是张量,代表N维数组:Flow的意思是流,代表基于数据流图的计算.把N维数字从流图的一端流动到另一端 ...