zoukankan      html  css  js  c++  java
  • select函数简单用法例程

    在《The Linux Programming Interface》的 63.2.1 The select() System Call中讲述了 select() 函数的用法

    下面是原型:

    1 #include <sys/time.h> /* For portability */
    2 #include <sys/select.h>
    3 int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
    4 struct timeval *timeout);
    5 
    6 Returns number of ready file descriptors, 0 on timeout, or –1 on error
    View Code

    其中 $readfds, $writefds, $exceptfds分别是交给select监控的读, 写, 异常文件描述符, timeout指定了监控的时间段,

    即在timeout的时间段内, 如果有设定的文件描述符设备就绪, 则立即返回, 否则超时后不再监控设定的设备.

    The $nfds argument must be set one greater than the highest file descriptor
    number included in any of the three file descriptor sets. This argument allows
    select() to be more efficient, since the kernel then knows not to check whether file
    descriptor numbers higher than this value are part of each file descriptor set.

    对应的操作文件描述符与文件描述符集合之间关系的宏有4个:

    1 #include <sys/select.h>
    2 void FD_ZERO(fd_set *fdset);
    3 void FD_SET(int fd, fd_set *fdset);
    4 void FD_CLR(int fd, fd_set *fdset);
    5 int FD_ISSET(int fd, fd_set *fdset);
    6     Returns true (1) if fd is in fdset, or false (0) otherwise
    View Code

    $FD_ZERO() initializes the set pointed to by fdset to be empty.
    $FD_SET() adds the file descriptor fd to the set pointed to by fdset.
    $FD_CLR() removes the file descriptor fd from the set pointed to by fdset.
    $FD_ISSET() returns true if the file descriptor fd is a member of the set pointed to
    by fdset.

    以下是书中的示例代码:

     1 /*************************************************************************
     2 *                  Copyright (C) Michael Kerrisk, 2015.                   *
     3 *                                                                         *
     4 * This program is free software. You may use, modify, and redistribute it *
     5 * under the terms of the GNU General Public License as published by the   *
     6 * Free Software Foundation, either version 3 or (at your option) any      *
     7 * later version. This program is distributed without any warranty.  See   *
     8 * the file COPYING.gpl-v3 for details.                                    *
     9 *************************************************************************/
    10 
    11 /* Listing 63-1 */
    12 
    13 /* t_select.c
    14 
    15    Example of the use of the select() system call to monitor multiple
    16    file descriptors.
    17 
    18    Usage as shown in usageError().
    19 */
    20 #include <sys/time.h>
    21 #if ! defined(__hpux)
    22 /* HP-UX 11 doesn't have this header file */
    23 #include <sys/select.h>
    24 #endif
    25 #include "tlpi_hdr.h"
    26 
    27 static void
    28 usageError(const char *progName)
    29 {
    30     fprintf(stderr, "Usage: %s {timeout|-} fd-num[rw]...
    ", progName);
    31     fprintf(stderr, "    - means infinite timeout; 
    ");
    32     fprintf(stderr, "    r = monitor for read
    ");
    33     fprintf(stderr, "    w = monitor for write
    
    ");
    34     fprintf(stderr, "    e.g.: %s - 0rw 1w
    ", progName);
    35     exit(EXIT_FAILURE);
    36 }
    37 
    38 int
    39 main(int argc, char *argv[])
    40 {
    41     fd_set readfds, writefds;//读, 写文件描述符
    42     int ready, nfds, fd, numRead, j;
    43     struct timeval timeout;//超时
    44     struct timeval *pto;
    45     char buf[10];                       /* Large enough to hold "rw" */
    46 
    47     if (argc < 2 || strcmp(argv[1], "--help") == 0)
    48         usageError(argv[0]);
    49 
    50     /* Timeout for select() is specified in argv[1] */
    51 
    52     if (strcmp(argv[1], "-") == 0) {
    53         pto = NULL;                     /* Infinite timeout */
    54     } else {
    55         pto = &timeout;
    56         timeout.tv_sec = getLong(argv[1], 0, "timeout");
    57         timeout.tv_usec = 0;            /* No microseconds */
    58     }
    59 
    60     /* Process remaining arguments to build file descriptor sets */
    61     
    62     nfds = 0;
    63     FD_ZERO(&readfds);
    64     FD_ZERO(&writefds);
    65 
    66     for (j = 2; j < argc; j++) {
    67         numRead = sscanf(argv[j], "%d%2[rw]", &fd, buf);//将文件描述符输入fd, 将输入/输出参数写入buf[]
    68         if (numRead != 2)
    69             usageError(argv[0]);
    70         if (fd >= FD_SETSIZE)
    71             cmdLineErr("file descriptor exceeds limit (%d)
    ", FD_SETSIZE);
    72 
    73         if (fd >= nfds)
    74             nfds = fd + 1;              /* Record maximum fd + 1 */
    75         if (strchr(buf, 'r') != NULL)
    76             FD_SET(fd, &readfds);
    77         if (strchr(buf, 'w') != NULL)
    78             FD_SET(fd, &writefds);
    79     }
    80 
    81     /* We've built all of the arguments; now call select() */
    82 
    83     ready = select(nfds, &readfds, &writefds, NULL, pto);
    84                                         /* Ignore exceptional events */
    85     if (ready == -1)
    86         errExit("select");
    87 
    88     /* Display results of select() */
    89 
    90     printf("ready = %d
    ", ready);
    91     for (fd = 0; fd < nfds; fd++)
    92         printf("%d: %s%s
    ", fd, FD_ISSET(fd, &readfds) ? "r" : "",
    93                 FD_ISSET(fd, &writefds) ? "w" : "");
    94 
    95     if (pto != NULL)
    96         printf("timeout after select(): %ld.%03ld
    ",
    97                (long) timeout.tv_sec, (long) timeout.tv_usec / 1000);
    98     exit(EXIT_SUCCESS);
    99 }
    View Code

     附件是书的代码包: 链接: http://pan.baidu.com/s/1qWYJ54w 密码: wmqb

  • 相关阅读:
    RUNOOB.COM-python网络编程-(python3.5.0)
    windows查看服务
    计算机网络里的一些理解
    如果面试有傻逼问道oracle怎么启动的
    推荐一个学习数据库的地方
    电脑中的驱动程序是什么,是干什么的
    Raspberry Pi 4B 之 Python开发
    Ubuntu20.04+EdgexFoundry边缘计算微服务搭建-----遇到的问题-----make build 被墙问题
    Raspberry Pi 4B + Ubuntu 20.04 server for arm64 的wifi配置
    关于PicoNeo开发环境的Unity3D+AndroidSDK配置
  • 原文地址:https://www.cnblogs.com/freudshow/p/5177454.html
Copyright © 2011-2022 走看看