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

  • 相关阅读:
    DataTables合并单元格(rowspan)的实现思路(多分组分类的情况)
    DataTables固定表格宽度(设置横向滚动条)
    用图片替代cursor光标样式
    DataTables获取指定元素的行数据
    任意表格(table)实现拖动列(column)改变列大小
    鼠标拖动改变DIV等网页元素的大小的最佳实践
    DataTables实现rowspan思路
    DataTables添加额外的查询参数和删除columns等无用参数
    击穿(强推---神仙代码)
    java jvm 参数 -Xms -Xmx -Xmn -Xss 调优总结
  • 原文地址:https://www.cnblogs.com/freudshow/p/5177454.html
Copyright © 2011-2022 走看看