问答

linux select多线程使用问题。

作者:admin 2021-07-12 我要评论

1.linux 两个线程 select同一个socket句柄,监控该句柄的可读状态,内核会怎么处理?可读时会内核会先唤醒队列里的其中一个线程处理,如果该线程读了,是否就不...

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)

1.linux 两个线程 select同一个socket句柄,监控该句柄的可读状态,内核会怎么处理?可读时会内核会先唤醒队列里的其中一个线程处理,如果该线程读了,是否就不会唤醒余下的线程?这样看在进程调度的过程中很有可能会引起惊群效应。
2.linux 两个线程 分别select不同的socket句柄,监控句柄的可读状态,内核会怎么处理?如果线程1的max_fd=3,线程2的max_fd=4。当fd=4可读时,应该不会有问题。当fd=3可读时,是否就会导致内核可能先会唤醒线程2?
3.正确做法是否就是所有的select都应该在一个线程上执行?

###
man 2 select
SYNOPSIS
       #include <sys/select.h>
       int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

DESCRIPTION
       select() allows a program to monitor multiple file descriptors, waiting until one or more of the file descriptors become "ready" for some class of I/O operation (e.g., input possible). A file
       descriptor is considered ready if it is possible to perform a corresponding I/O operation (e.g., read(2), or a sufficiently small write(2)) without blocking.
       select() can monitor only file descriptors numbers that are less than FD_SETSIZE; poll(2) and epoll(7) do not have this limitation. See BUGS.

可以观察到每次调用 select,都是传送要读写的 fd 集合给 内核,并阻塞等待内核响应。

当有读写事件发生的时候,select阻塞解除,同时 readfds,writefds,exceptfds 会清空并填入就绪的 fd 列表。

不存在你说的 1,2情况。

更仔细的内容请阅读 select的文档。

   Arguments
       The arguments of select() are as follows:

       readfds
              The  file descriptors in this set are watched to see if they are ready for reading.
              A file descriptor is ready for reading if a read operation will not block; in  par‐
              ticular, a file descriptor is also ready on end-of-file.

              After select() has returned, readfds will be cleared of all file descriptors except
              for those that are ready for reading.

       writefds
              The file descriptors in this set are watched to see if they are ready for  writing.
              A  file  descriptor is ready for writing if a write operation will not block.  How‐
              ever, even if a file descriptor indicates as writable,  a  large  write  may  still
              block.

              After  select()  has returned, writefds will be cleared of all file descriptors ex‐
              cept for those that are ready for writing.

       exceptfds
              The file descriptors in this set are watched for "exceptional conditions".  For ex‐
              amples of some exceptional conditions, see the discussion of POLLPRI in poll(2).

              After  select() has returned, exceptfds will be cleared of all file descriptors ex‐
              cept for those for which an exceptional condition has occurred.
###
  1. 会唤醒多个线程

    简单示例:

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/select.h>
    #include <pthread.h>
    
    void *thread_start(void *arg) {
        int retval;
    
        fd_set rfds;
        struct timeval tv;
    
        /* Watch stdin (fd 0) to see when it has input. */
        FD_ZERO(&rfds);
        FD_SET(0, &rfds);
    
        /* Wait up to 30 seconds. */
        tv.tv_sec = 30;
        tv.tv_usec = 0;
    
        retval = select(1, &rfds, NULL, NULL, &tv);
        /* Don't rely on the value of tv now! */
    
        if (retval == -1)
            perror("select()");
        else if (retval)
            printf("Data is available now.\n"); // 两次
        else
            printf("No data within 30 seconds.\n");
    }
    
    int main(void) {
        pthread_t t1, t2;
        pthread_create(&t1, NULL, thread_start, NULL);
        pthread_create(&t2, NULL, thread_start, NULL);
        pthread_join(t1, NULL);
        pthread_join(t2, NULL);
    }
    

    更多分析可以看 Select is fundamentally broken

  2. 看两个 fdset 里的文件描述符是否有交集(结论见第一个问题),和 max_fd 没关系
  3. 是,或者每个线程有独立的不重复的 fd_set

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • linux select多线程使用问题。

    linux select多线程使用问题。

  • 怎么查询数组里是否含有特定字符串的

    怎么查询数组里是否含有特定字符串的

  • 为什么需要熟知js模块化?

    为什么需要熟知js模块化?

  • TP5 sql语句问题

    TP5 sql语句问题

腾讯云代理商
海外云服务器