现在的位置: 首页 > 综合 > 正文

-D_REENTRANT机制

2013年08月06日 ⁄ 综合 ⁄ 共 1487字 ⁄ 字号 评论关闭

微笑

可重入:

lfl@ubuntu:/usr/include$ vi 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是一个宏。

lfl@ubuntu:/usr/include/i386-linux-gnu/bits$ vi 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 ())  //errno 是个宏,代表的是个函数。

#  endif

# endif /* !__ASSEMBLER__ */

#endif /* _ERRNO_H */

文件reentrant.c 的内容如下:

#include <errno.h>

int main()

{

    errno;

    return 0;

}

预处理的过程可以将宏进行替换,下面就进行预处理

lfl@ubuntu:~/test$ gcc -E reentrant.c -o reentrant.i

文件reentrant.i的内容如下:

# 2 "reentrant.c" 2

int main()

{

    (*__errno_location ()); //errno被替换成这个函数了。

    return 0;

}

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

例子:

int global_val 2;//定义个全局变量

void func()

{

    global_val++;

}

如果有N个进程调用该函数,而global_val是个全局变量,如果某个进程加上-D _REENTRANT,则可重入,即该进程的global_val不会受其他进程的影响;但是没加-D _REENTRANT的那N-1个进程调用该函数时变量global_val就会彼此影响,出现不可预料的结果。不会影响的原因是,加-D _REENTRANT的进程虽然调用的还是这个函数,但是不同的时该机制自动把该函数变成了

void func_r()

{

    global_val++;

}

跟其他进程调用的函数不同了,那么自然就不会影响本进程了,即可以重去。

抱歉!评论已关闭.