`select` on same fd from multiple threads

2020-06-21 08:41发布

What will happen if I call select on the same open file descriptor from multiple threads?

Is this documented somewhere?

2条回答
地球回转人心会变
2楼-- · 2020-06-21 09:23

According to the Linux manual page, select is a thread safe function and a cancellation point.

On Linux some operating systems, one thread will successfully enter select, while the other threads would be blocked (the body of select is a critical section). Whatever descriptors are returned to the first thread, then the second thread that successfully enters select would probably wake up immediately with the same set, since select is a level-triggered interface.

Thus, you can't use select to select on multiple sets of file descriptors simultaneously on Linux those operating systems.

Linux seems to support fully re-entrant execution, demonstrated with this test program:

void * reader (void *arg) {
    int *fds = (int *)arg;
    struct timeval to = { 2, 0 };
    fd_set rfds;

    FD_ZERO(&rfds);
    FD_SET(fds[0], &rfds);

    select(fds[0]+1, &rfds, 0, 0, &to);
}

int main () {
    int sp[2];
    pthread_t t[2];
    socketpair(AF_UNIX, SOCK_STREAM, 0, sp);
    pthread_create(&t[0], 0, reader, sp);
    pthread_create(&t[1], 0, reader, sp);
    pthread_join(t[0], 0);
    pthread_join(t[1], 0);
    return 0;
}

When timing this program on Linux (mine was 2.6.43), the program returned after 2 seconds, indicating both threads entered select concurrently.

查看更多
我命由我不由天
3楼-- · 2020-06-21 09:24

According to the POSIX 2008 select specification, there is nothing that prohibits two threads from both calling select at the same time.

It is reasonable to infer that if both threads are monitoring overlapping sets of file descriptors and some of the common file descriptors become readable or writable or have errors diagnosed, then both threads may end up with a report that the common file descriptors are ready. This cannot be guaranteed; there are timing issues to worry about, and it may depend on scheduling of the threads, etc. It also means one of the threads may end up not finding data to read on a file descriptor that it was told contained data to read, precisely because the other thread got there first. Any given byte of data will be read by just one of the threads.

查看更多
登录 后发表回答