IO函数之select()与pselect()、poll()与ppoll()简介

本文详细介绍了I/O多路复用技术中的select、pselect、poll与ppoll函数,包括它们的函数原型、参数说明、返回值及具体实例。通过这些函数,可以有效地监控多个文件描述符的状态,实现高效地I/O操作。
摘要由CSDN通过智能技术生成

目录

一:select()、pselect()函数

1.函数原型:

2.参数简介:

3.返回值:

4.select()实例

5.pselect()函数

6.pselect()实例

二:poll()函数与ppoll()函数

1.poll()函数原型

2.参数说明:


一:select()、pselect()函数

select()、pselect()函数与recv()和send()等直接操作文件描述符不同,它是对需要操作的文件描述符进行一个查询和监控的一个作用。

1.函数原型:

#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

//select
int select(int nfds, fd_set *readfds, fd_set *writefds, \
            fd_set *exceptfds, struct timeval *timeout);


struct timespec {
        long tv_sec;
        long tv_usec;  //微秒
}

//pselect
int pselect(int nfds, fd_set *readfds, fd_set *writefds, \
            fd_set *exceptfds, const struct timeval *timeout, \
            const sigset_t *sigmask);

struct timespec {
        long tv_sec;
        long tv_nsec;  //纳秒
}

2.参数简介:

  • nfds:一个整形变量,需要注意的是它会比描述符集合中的最大值+1。
  • readfds:这个文件描述符集合会监视文件集合中的任何文件是否有数据可读,当select函数返回时,readfds将清除其中不可读的文件描述符,只留下可读的文件描述符,即可被函数recv()、read()等进行读数据的操作。
  • writefds:这个文件描述符集合会监视文件集合中的任何文件是否有数据可写,当select函数返回时,writefds将清除其中不可写的文件描述符,只留下可写的文件描述符,即可被函数send()、write()等进行写数据的操作。
  •  exceptfds:这个文件描述符集合会监视文件集合中的任何文件是否发生错误,当然, 它也有另一个用途, 就是能够监视外带的数据OOB,将外数据使用MSG_OOB标志发送到套接字上,当select函数返回时,readfds将清除其中的其他文件描述符, 只留下可读OOB数据。
  • timeout:设置超时时间,等待期间会一直阻塞,设置为0时, 会立即返回。
  • sigmask:信号掩码。

3.返回值:

  • 返回值为0:超时返回为0
  • 返回值为大于0:监视的文件集中有文件描述符符合要求。
  • 返回值为-1:表示发生错误,错误值由errno指定。
含义含义
EBADF参数s不是合法描述符EINVAL传递了不合法参数
EINTR接收到中断信号ENOMEM没有足够内存

函数select()和pselect()允许监视多个文件描述符,当一个或者多个监视的文件描述符准备就绪,可以进行IO操作的时候返回。当所有的文件集合均为NULL,则表示等待一段时间。

通常使用4个宏操作文件描述符的集合。

FD_ZERO():清理文件描述符集合。

FD_SET():向某个文件描述符集合中加入文件描述符。

FD_CLR():从某个文件描述符的集合中取出某个文件描述符。

FD_ISSET():测试某个文件描述符是否为某个集合中一员。

4.select()实例

#include <stdio.h>
#include <sys/time.h>
#include <sys/tpyes.h>
#include <unistd.h>

int main(void)
{
    fd_set rd;
    struct timeval tv;
    int err;
    FD_ZERO(&rd);
    FD_SET(0, &rd);    /*添加标准输入*/
    tv.tv_sec = 5;
    tv.tv_usec = 0;
    err = selec(0+1, &rd, NULL, NULL, &tv);

    if (err == -1)
        peeror("select()");
    else if (err)
        printf("Data is avaliable now!\n");
    else
        printf("time out \n");
    return 0;
}

5.pselect()函数

基本上与select()使用一致,最大的区别是pselect()能够多一个信号处理, 同时pselect设置后无法无法修改延时的值,select()后面可以改变timeout的值。

6.pselect()实例

int child_events = 0;
void child_sig_handler (int x) {
    child_events++;
    signal(SIGCHLD, child_sig_handler);
}

int main(int argc, char *argv[])
{
    sigset_t sigmask, orig_sigmask;
    sigmptyset(&sigmask);   /*清空信号*/
    sigaddset(&sigmask, SIGCHLD);
    
    /*设定信号SIG_BLOCK的掩码sigmask, 并将原始的掩码保持至orig_sigmask*/
    sigprocmask(SIG_BLOCK,&sigmask,&orig_sigmask);
    signal(SIGCHLD, child_sig_handler);
    while(1) {
        for(; child_events > 0; child_events--) {
            /*处理动作*/
        }
        r = pselect(nfds, &rd, &wr, &er, 0, &orig_sigmask);
        /*其他操作*/
    }
    return 0;
}

二:poll()函数与ppoll()函数

除了select函数进行文件描述符的监视, 还有一组函数也有相似的功能,就是poll()与ppoll()函数。

1.poll()函数原型

#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
int ppoll(struct pollfd *fds, nfds_t nfds, const stuct timespec *timeout,\
           const sigset_t *sigmask);

struct pollfd {
       int fd;                /*文件描述符*/
       short events;          /*请求的事件*/
       short revents;         /*返回的事件*/
};

2.参数说明:

  • fds:指向结构pollfd数组的指针,监视的文件描述符和条件放在里面。
  • nfds:比监视的最大描述符大1的值。
  • timeout:超时时间,单位毫秒,为负值时, 表示永远等待。

3.返回值说明:

  • 返回值为0:超时返回为0
  • 返回值为大于0:监视的文件集中有文件描述符符合要求。
  • 返回值为-1:表示发生错误,错误值由errno指定。
含义含义
EBADF参数s不是合法描述符EINVAL传递了不合法参数
EINTR接收到中断信号ENOMEM没有足够内存
events的值及含义
含义含义
POLLIN有数据到来,文件描述符可读POLLNVAL非法请求
POLLRPI有紧急数据可读,列如外带数据POLLRDNORM与POLLIN相同
POLLOUT文件可写POLLRDBAND优先数据可读
POLLRDHUP流式套接字半关闭POLLWRNORM与POLLOUT相同
POLLERR错误发生POLLWRBAND优先数据可写
POLLHUP关闭

区别基本与select()和pseletc()相同;

具体实例参考上面的select()和pselect();

fcntl(s, F_SETFL, NONBLOCK);  设置为非阻塞。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值