Timerek

interval timer set/get itimer

struct itimerval { 
	struct timeval it_interval; /* Interval for periodic timer */ 
	struct timeval it_value; /* Current value (time until next expiration) */ 
};

Timeval (timeinterval)

struct timeval { 
	time_t tv_sec; /* Seconds */
	 suseconds_t tv_usec; /* Microseconds (long int) */ 
};

Kérdés: Milyen idővel kapcsolatos API hívásokat tudunk még?

 setitimer(ITIMER_REAL, &timer, NULL); //result = 0, if it is good
    //when expires, a signal will be sent to the process, and it restarts
    //1. parameter ITIMER_REAL - real time, ITIMER_VIRTUAL (during process execution)

Timer fd : nem nézzük

Multitasking Bash-ben

új kombináció: Ctrl+Z

  • fg
  • bg
  • & (háttérben indítás)
  • (while true; do date; sleep 1; done)

I/O Multiplexelés

File descriptorokra várás: select , poll Mikor áll készen egy file?

  • hagyományos file-oknál midig készen áll írásra vagy olvasásra
  • pipie-ok és FIFO-k
    • Ha van olvasható adat, akkor POLLIN
    • Ha van lehetsőég írni akkor POLLOUT
    • Ha le van zárva az írás illetve olvasási vég: POLLHUP ill POLLERR

Select

  • régebbi API, template-ekkel való kommunikálás, int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
  • pontos timeval struktúra
  • visszatérési értékek
    • timeout: 0
    • hiba: -1
    • sikeres: pozitív, a készen lévő fd-k számával egyezik

Poll

  • újabb API, de ugyanaz kernel hívások
  • egy struct-ba vannak a fd-k felsorolva
struct pollfd { 
	int fd; /* File descriptor */ 
	short events; /* Requested events bit mask */ 
	short revents; /* Returned events bit mask */ 
};
int poll(struct pollfd fds[], nfds_t nfds, int timeout); 
/* timeout 0 = no block, -1 legalább egy, >0 várakozik

Poll és Select hátrányai

  • Ez egy blocking művelet, de nem lehet egyszerre signalra vagy poll-ra szűrni.
  • sok nyitott file esetén sok erőforrásba kerül ellenőrizni a file-okat.
  • mindig az összes filedescriptort végignézik
  • egy struct -on keresztül kommunikál a kernel oda és vissza performance!
  • a kernel nem tartja nyilván speciálisan, hogy melyik fd-kre figyelünk, minden poll hívás egy új figyelést indít ell

(p)select és (p)poll

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

Atomikusan ekvivalens:

sigset_t origmask; 
sigprocmask(SIG_SETMASK, &sigmask, &origmask); 
ready = select(nfds, &readfds, &writefds, &exceptfds, timeout); sigprocmask(SIG_SETMASK, &origmask, NULL); /* Restore signal mask */

(e)select és (e)poll

  • nem signalok segítségével, hanem egy speciális fd-követő fd-vel valósul meg
  • flexibilisebb mint a signal alapú küldés
  • nem UNIX kompatibilis
  • lifecycle-je hasonló egy objektuméhoz.

létrehozás: polls = int epoll_create() módosítás int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev); hozzáadjuk a epfd-figyelt listájához az fd-t EPOLL_CTL_ADD -al

Példa előkészítésre:

int epfd; 
struct epoll_event ev;
epfd = epoll_create(5); 
if (epfd == -1) errExit("epoll_create"); 
ev.data.fd = fd; ev.events = EPOLLIN; 
if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, ev) == -1) errExit("epoll_ctl");

Várakosára: int epoll_wait(int epfd, struct epoll_event *evlist, int maxevents, int timeout);

Megjegyzés: Itt mindig akkor történt a feloldás, amikor az írás/olvasás a pipe-ból/ba lehetségessé vált. Ez a “Level-triggered” I/O Van lehetőség arra, hogy akkor oldódjon fel a parancs, amikor írás/olvasás történt a pipe-ból/ba. Mi a különbség?