1 / 11

Luku 23 – Signal Driven IO

Luku 23 – Signal Driven IO. Periaate Esimerkki. Signal Driven IO. Kernel lähettää ohjelmalle signaalin, kun jotain tapahtuu descriptorille Signal Driven IO:ta kutsuttu joskus virheellisesti asynkroniseksi IO:ksi SIGIO signaali. Vaiheet. SIGIO käsittelijän määritteleminen

zahina
Download Presentation

Luku 23 – Signal Driven IO

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Luku 23 – Signal Driven IO • Periaate • Esimerkki

  2. Signal Driven IO • Kernel lähettää ohjelmalle signaalin, kun jotain tapahtuu descriptorille • Signal Driven IO:ta kutsuttu joskus virheellisesti asynkroniseksi IO:ksi • SIGIO signaali

  3. Vaiheet • SIGIO käsittelijän määritteleminen • Socketin omistaja pitää määritellä F_SETOWN komennolla fcntl kutsulle • Signal Driven IO täytyy kytkeä päälle F_SETFL komennolla fcntl kutsulle (tai FIOASYNC ioctl)

  4. SIGIO UDP sockettien kanssa • SIGIO signaali lähetetään prosessille kun: • Datagrammi vastaanotetaan • Asynkroninen virhe tapahtuu

  5. SIGIO ja TCP – Onko järkee vai ei? • - EI! • koska SIGIO lähetetään useasta syystä, eikä voida päätellä mitä socketille on tapahtunut

  6. Signal Driven IO:n käyttötarkoitukset • Ainoa tunnettu käyttö NTP palvelimessa, joka saa signaalien avulla tarkan tiedon pakettien saapumisajankohdista • SIGIO käsittelijä vastaanottaa datagrammit ja lisää ne jonoon, jota palvelimen pääsilmukka tyhjentää (kuva s. 665)

  7. Esimerkki: Jonon tietorakenne ja globaalit määrittelyt • typedef struct { • void *dg_data; /* ptr to actual datagram */ • size_t dg_len; /* length of datagram */ • struct sockaddr *dg_sa; /* ptr to sockaddr{} w/client's address */ • socklen_t dg_salen; /* length of sockaddr{} */ • } DG; • static DG dg[QSIZE]; /* queue of datagrams to process */ • static long cntread[QSIZE+1]; /* diagnostic counter */ • static int iget; /* next one for main loop to process */ • static int iput; /* next one for signal handler to read into */ • static int nqueue; /* # on queue for main loop to process */ • static socklen_t clilen;/* max length of sockaddr{} */ • static void sig_io(int); • static void sig_hup(int);

  8. dg_echo (1/2) • void • dg_echo(int sockfd_arg, SA *pcliaddr, socklen_t clilen_arg) • { • int i; • const int on = 1; • sigset_t zeromask, newmask, oldmask; • sockfd = sockfd_arg; • clilen = clilen_arg; • for (i = 0; i < QSIZE; i++) { /* init queue of buffers */ • dg[i].dg_data = Malloc(MAXDG); • dg[i].dg_sa = Malloc(clilen); • dg[i].dg_salen = clilen; • } • iget = iput = nqueue = 0; • Signal(SIGHUP, sig_hup); • Signal(SIGIO, sig_io); • Fcntl(sockfd, F_SETOWN, getpid()); • Ioctl(sockfd, FIOASYNC, &on); • Ioctl(sockfd, FIONBIO, &on); • Sigemptyset(&zeromask); /* init three signal sets */ • Sigemptyset(&oldmask); • Sigemptyset(&newmask); • Sigaddset(&newmask, SIGIO); /* signal we want to block */ • Sigprocmask(SIG_BLOCK, &newmask, &oldmask);

  9. dg_echo(2/2) • for ( ; ; ) { • while (nqueue == 0) • sigsuspend(&zeromask); /* wait for datagram to process */ • /* 4unblock SIGIO */ • Sigprocmask(SIG_SETMASK, &oldmask, NULL); • Sendto(sockfd, dg[iget].dg_data, dg[iget].dg_len, 0, • dg[iget].dg_sa, dg[iget].dg_salen); • if (++iget >= QSIZE) • iget = 0; • /* 4block SIGIO */ • Sigprocmask(SIG_BLOCK, &newmask, &oldmask); • nqueue--; • } • }

  10. SIGIO käsittelijä • static void • sig_io(int signo) • { • ssize_t len; • int nread; • DG *ptr; • for (nread = 0; ; ) { • if (nqueue >= QSIZE) • err_quit("receive overflow"); • ptr = &dg[iput]; • ptr->dg_salen = clilen; • len = recvfrom(sockfd, ptr->dg_data, MAXDG, 0, • ptr->dg_sa, &ptr->dg_salen); • if (len < 0) { • if (errno == EWOULDBLOCK) • break; /* all done; no more queued to read */ • else • err_sys("recvfrom error"); • } • ptr->dg_len = len; • nread++; • nqueue++; • if (++iput >= QSIZE) • iput = 0; • } • cntread[nread]++; /* histogram of # datagrams read per signal */ • }

More Related