加入收藏 | 设为首页 | 会员中心 | 我要投稿 拼字网 - 核心网 (https://www.hexinwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Handling of asynchronous events---reference

发布时间:2021-01-27 07:29:08 所属栏目:Linux 来源:网络整理
导读:http://www.win.tue.nl/~aeb/linux/lk/lk-12.html 12.?Handling of asynchronous events One wants to be notified of various events,like data that has become available,files that have changed,and signals that have been raised. FreeBSD has the ni

The pselect system call has a 7-parameter prototype (the 7th parameter being the size of the 6th?sigmask?parameter),but most architectures cannot handle 7-parameter system calls,so there is also a 6-parameter version where the 6th parameter is a pointer to a struct that has the last two parameters. Unlike the POSIX library routine,the system call does return the leftover part of the timeout.

This system call starts changing the signal mask,and ends restoring it. However,if it was interrupted by a signal,this signal should be delivered,while the signal mask might block it. This is solved by the recent?TIF_RESTORE_SIGMASK?mechanism in the kernel. When the pselect system call returns after being interrupted by a signal,it does not immediately restore the original signal mask,but first runs the user's signal handler,and first upon return from that the original signal mask is restored.

12.4?poll

The?poll()?system call is rather similar to?select(). The prototype is

struct pollfd {
    int   fd;         /* file descriptor */
    short events;     /* requested events */
    short revents;    /* returned events */
};

int poll(struct pollfd *fds,nfds_t nfds,int timeout);

where the fields?events?amd?revents?are bitmasks indicating for what events?fd?should be watched,and what conditions actually occurred. The timeout is in milliseconds; a negative number means an infinite timeout.

ppoll

Just like?pselect?is a version of select that allows safe handling of signals,?ppoll?is such a version of?poll. The prototype is

int ppoll(struct pollfd *fds,const struct timespec *timeout,const sigset_t *sigmask);

12.5?epoll

When the number of file descriptors becomes very large,the?select()?and?poll()?mechanisms become inefficient. With N descriptors,O(N) information must be copied from user space to kernel and vice versa,and loops of length O(N) are needed to test the conditions.

Solaris introduced the?/dev/poll?mechanism (see?poll(7d)?on Solaris),where the idea is that one does the copy from user space to kernel only once (by writing an array of struct pollfd's to?/dev/poll) and gets only interesting information back (via an ioctl on this device that copies the interesting struct pollfd back to userspace).

Linux tries something similar using the three system calls?epoll_create,?epoll_ctl,?epoll_wait?(added in 2.5.44,see?epoll(7)). Benchmarks seem to indicate that the performance is comparable to that of select and poll until one has thousands of descriptors,only a small fraction of which is ready. (And then epoll is clearly better.) In most tests,the FreeBSD kqueue wins.

For a discussion of these and several other mechanisms,especially for the context of web servers,see?.

epoll_pwait

Just like?pselect?and?ppoll?are versions of?select?and?poll,there is (since 2.6.19) a?epoll_pwait?version of?epoll_wait?that includes a signal mask.

12.6?dnotify

The above was about notification about file descriptors that become ready for I/O. A different type of notification is that about file system events. In 2.4.0-test9 the?dnotify?feature was introduced. Today it is obsoleted by?inotify?(see below). See?Documentation/dnotify.txt?and?fs/dnotify.c.

The idea was that one could register interest in changes in a directory?dir?using?fd = open(dir,O_RDONLY)?followed by?fcntl(fd,F_NOTIFY,...). Notification occurs via delivery of a signal.

/* dnotify demo,basically from Documentation/dnotify.txt */
#define _GNU_SOURCE
#include 
#include 
#include 
#include 

static volatile int dir_fd;

/ A very weak interface: we report that something changed,but
the only info is in which directory,but not what the change is.
/
static void handler(int sig,siginfo_t si,void data) {
dir_fd = si->si_fd;
}

int main(void) {
struct sigaction act;
int fd;

    act.sa_sigaction = handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = SA_SIGINFO;
    sigaction(SIGRTMIN + 1,&act,NULL);

    fd = open(".",O_RDONLY);
    fcntl(fd,F_SETSIG,SIGRTMIN + 1);
    fcntl(fd,DN_MODIFY|DN_CREATE|DN_DELETE|DN_RENAME|DN_MULTISHOT);

    while (1) {
            pause();
            printf("Got some event on fd=%dn",dir_fd);
    }

}

(编辑:拼字网 - 核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!