我需要在多线程读取呼叫中保护fd吗?

时间:2017-05-01 07:33:53

标签: 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调用是否保证在这种情况下正确的线程安全?

1 个答案:

答案 0 :(得分:1)

多个线程可以安全地同时在同一个文件描述符上调用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 ... */

但是,这很奇怪,因为如果你使用共享内存和互斥,你也可以使用部分共享内存和条件变量来实现从编写器到读取器的信令,而不是涉及文件描述符。