c - Linux 3.5 : Safe to `read(2)` from same fd `open(2)` `/dev/urandom` from multiple threads?

标签 c linux multithreading pthreads linux-device-driver

这样做安全吗:

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/

相关文章:

代码浏览 : How to find out which function a function pointer is pointing to?

linux - 获取某些行

java - for-each 迭代线程安全吗?

c - pthread_cond_broadcast 在 POSIX 中没有忙等待

c - "Copy string from array to array"使用指针的函数

c - 重新分配和内存移动

带指针的 C 输出

python - Bash/Python 将多个路径收集到一个并将文件名替换为 '*' 字符

即使在对等方挂断后,poll() 也能返回 POLLIN 事件吗?

c# - 这种对 Monitor.Wait/Pulse 的使用是否存在竞争条件?