strerror线程安全分析

简介: strerror线程安全分析.pdf 导读 strerror是否线程安全了? 1 errno是否线程安全? 1 附1:strerror源码 2 附2:__strerror_r源码 2   strerror是否线程安全了? 答案是NO,但它有个线程安全的版本:strerror_r。
img_e25d4fb2f8de1caf41a735ec53088516.pngstrerror线程安全分析.pdf

导读

strerror是否线程安全了? 1

errno是否线程安全? 1

1strerror源码 2

2__strerror_r源码 2

 

strerror是否线程安全了?

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

#include 

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 

 

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;

}

 

1strerror源码

// glibc-2.14\string\strerror.c

#include 

 

/* 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 0 || 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 

 

      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 

{

  *q++ = '-';

  ++unklen;

}

      if (unklen 

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)

 

 

相关文章
|
2月前
|
Linux
一个进程最多可以创建多少个线程基本分析
一个进程最多可以创建多少个线程基本分析
237 1
|
4月前
|
监控 Linux 编译器
多线程死锁检测的分析与实现(linux c)-有向图的应用
在日常的软件开发中,多线程是不可避免的,使用多线程中的一大问题就是线程对锁的不合理使用造成的死锁,死锁一旦发生,将导致多线程程序响应时间长,吞吐量下降甚至宕机崩溃,那么如何检测出一个多线程程序中是否存在死锁呢?在提出解决方案之前,先对死锁产生的原因以及产生的现象做一个分析。最后在用有向环来检测多线程中是否存在死锁的问题。
58 0
|
4月前
|
消息中间件 NoSQL Java
线程池 - 分析与实现(一)
线程池 - 分析与实现(一)
|
4月前
|
缓存 NoSQL Java
后端接口性能优化分析-多线程优化(中)
后端接口性能优化分析-多线程优化
57 0
|
4月前
|
消息中间件 存储 监控
后端接口性能优化分析-多线程优化(上)
后端接口性能优化分析-多线程优化
73 0
|
5月前
|
数据采集 人工智能 数据可视化
Scala多线程爬虫程序的数据可视化与分析实践
Scala多线程爬虫程序的数据可视化与分析实践
|
3天前
|
Java
【Java多线程】分析线程加锁导致的死锁问题以及解决方案
【Java多线程】分析线程加锁导致的死锁问题以及解决方案
11 1
|
17天前
|
SQL Dubbo Java
案例分析|线程池相关故障梳理&总结
本文作者梳理和分享了线程池类的故障,分别从故障视角和技术视角两个角度来分析总结,故障视角可以看到现象和教训,而技术视角可以透过现象看到本质更进一步可以看看如何避免。
83752 0
|
19天前
|
安全
并发编程之变量的线程安全分析的详细解析
并发编程之变量的线程安全分析的详细解析
11 0
|
2月前
|
存储 算法 Linux
【Linux 系统标准 进程资源】Linux 创建一个最基本的进程所需的资源分析,以及线程资源与之的差异
【Linux 系统标准 进程资源】Linux 创建一个最基本的进程所需的资源分析,以及线程资源与之的差异
137 0