我曾经认为所有可重入函数都是线程安全的。但是我读了Reentrancy page in Wiki,它发布的代码是“完全可重入的,但不是线程安全的。因为它不能确保执行期间全局数据处于一致状态”
int t;
void swap(int *x, int *y)
{
int s;
s = t; // save global variable
t = *x;
*x = *y;
// hardware interrupt might invoke isr() here!
*y = t;
t = s; // restore global variable
}
void isr()
{
int x = 1, y = 2;
swap(&x, &y);
}
我不明白它的解释。为什么此函数不是线程安全的?是因为在线程执行期间将更改全局变量
int t
吗? 最佳答案
为了给出更通用的答案,可重入仅在功能级别上。这意味着该函数的一个调用不会更改可以更改第二个调用的功能的状态。
在给出的示例中,全局变量在函数的两次调用之间未更改。函数内部发生的情况对函数的每次调用都没有影响。
不可重入函数的一个示例是strtok
例如,不可能将2个解析循环与其嵌套在一起:
/* To read a several lines of comma separated numbers */
char buff[WHATEVER], *p1, *p2;
p1 = strtok(buff, "\n");
while(p1) {
p2 = strtok(p1, ",");
while(p2) {
atoi(p2);
p2 = strtok(NULL, ",");
}
}
p1 = strtok(NULL, "\n");
}
这是行不通的,因为外部strtok循环的状态被第二个调用所破坏(必须使用可重入变体
strtok_r
)。关于c - 为什么此代码是可重入的但不是线程安全的,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9116598/