gpt4 book ai didi

c++ - rand_r 是否是真正的线程安全的?

转载 作者:可可西里 更新时间:2023-11-01 18:02:14 26 4
gpt4 key购买 nike

嗯,rand_r 函数应该是一个线程安全函数。然而,通过它的实现,我不敢相信它可以使自己不被其他线程改变。假设两个线程将使用相同的变量种子同时调用 rand_r。所以会发生读写竞争。下面列出了 glibc 实现的代码 rand_r。有人知道为什么 rand_r 被称为线程安全的吗?

 int
rand_r (unsigned int *seed)
{
unsigned int next = *seed;
int result;

next *= 1103515245;
next += 12345;
result = (unsigned int) (next / 65536) % 2048;

next *= 1103515245;
next += 12345;
result <<= 10;
result ^= (unsigned int) (next / 65536) % 1024;

next *= 1103515245;
next += 12345;
result <<= 10;
result ^= (unsigned int) (next / 65536) % 1024;

*seed = next;

return result;
}

最佳答案

您可以想到线程安全的三个级别,为了便于引用,我将在此处编号。

1) 根本不是线程安全的。从多个线程并发调用该函数是不安全的。例如,strtok

2) 相对于系统线程安全。从多个线程并发调用该函数是安全的,前提是不同的调用对不同的数据进行操作。例如,rand_rmemcpy

3) 关于数据的线程安全。从多个线程并发调用该函数是安全的,即使作用于相同的数据也是如此。例如 pthread_mutex_lock

rand_r 处于第 2 级,C 上下文中的约定(特别是在 POSIX 规范中)将其称为“线程安全”。

在其他一些语言中,例如 Java,惯例是将级别 3 称为“线程安全”,将其他所有内容称为“非线程安全”。因此,例如 java.util.Vector 是“线程安全的”,而 java.util.ArrayList 是“非线程安全的”。当然 java.util.ArrayList 的所有方法都在第 2 层。所以来自 Java 的程序员可能会自然地调用 rand_rmemcpy ”不是线程安全的”。

在 C 语言中,约定是不同的,也许是因为内部同步的数据结构一开始就很少见。在 C 的上下文中,您可能会问“文件句柄是线程安全的吗?”,并且谈论的是级别 3,但是当问“这个函数是线程安全的吗?”时这通常意味着 2 级。

关于c++ - rand_r 是否是真正的线程安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2772090/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com