这样做安全吗:
int fd;
void thread_main()
{
char buf[M];
ssize_t r = read(fd, buf, M);
assert(r == M);
...
}
int main()
{
fd = open("/dev/urandom", O_RDONLY);
for (int i = 0; i < N; i++)
start_thread(i);
for (int i = 0; i < N; i++)
join_thread(i);
}
即:从主线程open(2)
ing "/dev/urandom"
后,read(2)
是否安全code> 来自它与不同线程上下文不同步?
断言在什么情况下会触发?两个线程会得到相同的数据吗?会出什么问题?
最佳答案
只要您的代码不会崩溃,它就是安全的。 assert
永远不会触发。没有两个线程会(应该)获得相同的随机数据(两个线程获得两个“不同”的随机序列的可能性很小,但仍然有可能顺便相同,所以这不能 100% 保证)。
/dev/urandom
永远不会阻止或返回比您尝试读取的字节数更少的字节数,但是,如果您读取的数据量足够大,它最终会耗尽熵,因此随机数最终会略有下降。通常情况下,这仍然足够好,而且在发生这种情况之前也需要一段时间,但这是需要注意的事情(大多数人不需要关心,但它可能不是可以接受的,取决于你做什么)。
read
/write
是线程安全的(只要它们不会崩溃或损坏数据或将描述符留在未定义状态)并且在这种特殊情况下 也应该不 在不同进程的读取/写入之间混合/拆分字节。但是,一般来说,read
/write
不保证这一点。它们可能在某些设备上混合并发读/写数据。
但这应该不是问题,因为如果您得到一些其他随机位而其他人得到一些(不同的)位,随机位仍然是随机的。
如果您认为这对您来说是个问题,请使用 readv
,它保证 严格的原子性(永远不会混合/混合)。任何进/出 readv
/writev
的东西都作为一个原子单元处理,总是(除了在管道上,当超过 PIPE_BUF
,如 rodrigo 所指出的)。
关于c - Linux 3.5 : Safe to `read(2)` from same fd `open(2)` `/dev/urandom` from multiple threads?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12245054/