linux - 我需要在多线程读取调用中保护 fd 吗?

标签 linux kernel locking pthreads pipe

read 系统调用是否意味着内核内部描述符的同步?我见过一些代码只使用 read 调用来同步和协调多个消费者线程,如下所示:

rfd,wfd = pipe() or socketpair(); // setup fd

// a single writer:
write(wfd, ...);

// multiple read threads, each blocks on read:
read(rfd, work);   // my questions is here
// do the work assigned by writer

虽然我曾经认为必须使用像 pthread_mutex 这样的显式锁,如下所示:

pthread_mutex_t lock;
// work threads:
pthread_mutex_lock(&lock);
read(rfd, work);
pthread_mutex_unlock(&lock);
// do work

所以我的问题是在这种情况下是否需要显式锁定?在这种情况下,read 调用是否保证适当的线程安全?

最佳答案

多个线程同时对同一个文件描述符调用read()是安全的,但是read()调用不会同步内存(它不是列在 the functions specified by POSIX 中)。

这意味着如果您通过文件描述符本身传输所有需要的信息,那么仅依赖 read() 才是安全的。如果你想使用共享内存,你还需要一个内存同步函数 - 你不必在 read() 上持有锁,但是有一个模式是安全的:

/* writer */

pthread_mutex_lock(&lock);
/* ...write to shared memory... */
pthread_mutex_unlock(&lock);
write(wfd, ...);

/* readers */

read(rfd, ...);
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);
/* ... read from shared memory ... */

然而,这会很奇怪,因为如果您使用共享内存和互斥锁,您还不如使用部分共享内存和一个条件变量来实现从写入器到读取器的信号传递,而不是涉及文件描述符。

关于linux - 我需要在多线程读取调用中保护 fd 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43715772/

相关文章:

linux - 在 Linux 终端中将文件内容复制到剪贴板

linux - Ubuntu 图形用户界面应用程序

c - 将结构数组从用户空间传递到内核空间然后再返回时遇到问题

.net - 我需要在 ASP.NET 中使用 AJAX 关心线程安全吗?

linux - 命令挂起 head/netcat

linux - Lazarus 从 32 位交叉编译到 64 位

operating-system - 为什么 xv6 调度程序在每个循环开始时调用 sti()?

c - 使用 netlink 从旧内核上的套接字获取 inode

python - Python中是否有参数锁定机制?

c# - 防止两个线程进入具有相同值的代码块