重入,可理解为重新进入。
一般使用全局变量或static变量的都是不可重入变量,因为本来A程序要用a变量,结果被B程序拿走了a,然后修改了它的值,这时A程序再用a,得到的就不是
它想要的值了。
就像水流,有一直向前流的,也有分叉的。全局变量、静态变量等被几个函数同时使用,即共享时就相当于分叉,这时我们就需要保证信号流向不分叉即可。
主要用于多任务环境中,一个可重入的函数简单来说就是可以被中断的函数,也就是说,可以在这个函数执行的任何时刻中断它,转入OS调度下去执行另外一段代码,而返回控制时不会出现什么错误;而不可重入的函数由于使用了一些系统资源,比如全局变量区,中断向量表等,所以它如果被中断的话,可能会出现问题,这类函数是不能运行在多任务环境下的。
char *getenv (char *name)//不可重入函数
{
int i, nxt;
WATCHDOG_RESET();
for (i=0; env_get_char(i) != '\0'; i=nxt+1) { //找到一个环境变量的‘\0'
int val; //每个环境变量以‘\0'结尾
for (nxt=i; env_get_char(nxt) != '\0'; ++nxt) {
if (nxt >= CFG_ENV_SIZE) { //所有的环境变量加起来最大为
return (NULL); //CFG_ENV_SIZE字节
}
}
if ((val=envmatch((uchar *)name, i)) < 0) //不是这变量
continue;
return ((char *)env_get_addr(val)); //找到并输出这个变量
}
return (NULL);
}
int getenv_r (char *name, char *buf, unsigned len)//可重入函数
{
int i, nxt;
for (i=0; env_get_char(i) != '\0'; i=nxt+1) {
int val, n;
for (nxt=i; env_get_char(nxt) != '\0'; ++nxt) {
if (nxt >= CFG_ENV_SIZE) {
return (-1);
}
}
if ((val=envmatch((uchar *)name, i)) < 0)
continue;
/* found; copy out */
n = 0;
while ((len > n++) && (*buf++ = env_get_char(val++)) != '\0')
; //存入字符缓冲区
if (len == n)
*buf = '\0';
return (n);
}
return (-1);
}
getenv函数是直接返回这个找到的环境变量在DDR中环境变量处的地址,
而getenv_r函数的做法是找到了DDR中环境变量地址后,将这个环境变量复制一份到提供的buf中,而不动原来DDR中环境变量。
所以差别就是:
getenv中返回的地址只能读不能随便乱写,
而getenv_r中返回的环境变量是在自己提供的buf中,是可以随便改写加工的。