Uživatelské nástroje

Nástroje pro tento web


inter-process-comm

Toto je starší verze dokumentu!


Mezi-procesová komunikace

  • sdílená paměť
  • nepojmenovaná roura (pipe)
  • pojmenovaná roura
  • unix soket
  • POSIX_Message_Queues
  • DBus

Nepojmenovaná roura

  • jednosměrná
  • dva konce - producent a konzument
  • do roury by měl zapisovat nebo z ní číst pouze jeden proces
    • čtení je destruktivní (přečtení jedním procesem zruší možnost čtení procesem druhým)
    • zápis/čtení do velikosti 'PIPE_BUF' by mělo být atomické (pokud do roury budou zapisovat dva procesy, tak zápisy do uvedené velikosti by se neměli pomíchat dohromady)
  • roura se vytváří příkazem pipe
    • parametrem je int[2], kde index 0 je deskriptor pro zápis a index 1 pro čtení
  • rouru je potřeba na konci uzavřít příkazem close
  • zapisovat lze příkazem write, číst příkazem read
  • při čtení z roury, zavřené na druhé straně, se přečte znak EOF
  • při zápisu do roury, zavřené na druhé straně, se generuje signál SIGPIPE (ukončí běh aplikace)
#include <unistd.h>
 
int pipefd[2];
 
pipe(pipefd);
..
close(pipefd[0]);
close(pipefd[1]);

Spojení s procesem jednosměrně

  • poepen
  • pclose

Spojení s procesem obousměrně

  • vytvořit rouru ipipe pro jeden směr (rodič → potomek)
  • vytvořit rouru opipe pro druhý směr (potomek → rodič)
  • provést fork
  • zavřít nepoužívané deskriptory
    • v potomkovi zavřít deskriptor pro zápis do ipipe
    • v potomkovi zavřít deskriptor pro čtení do opipe
    • v rodiči zavřít deskriptor pro zápis do opipe
    • v rodiči zavřít deskriptor pro čtení do ipipe
  • ostatní deskriptory použít pro zpracování
    • můžeme z nich číst/zapisovat
    • můžeme je použít jako náhradu pro stdin (STDIN_FILENO), stderr (STERR_FILENO) nebo stdout (STDOUT_FILENO)

Neblokující roura

  • standardně je čtení a zápis blokující
  • pro neblokující je potřeba změnit nastavení přes syscall fcntl (pro každý konec roury)
// set non-blocking mode
if (fcntl(pipe_fd, F_SETFL, fcntl(pipe_fd, F_GETFL) | O_NONBLOCK) == -1) {
  fprintf(stderr,"Cannot set non-blocking mode to pipe\n");
}
// set blocking mode
if (fcntl(pipe_fd, F_SETFL, fcntl(pipe_fd, F_GETFL) & ~O_NONBLOCK) == -1) {
  fprintf(stderr,"Cannot set blocking mode to pipe\n");
}
  • chování funkcí read a write se v non-blocking režimu mění
  • pokud nejsou žádná data ke čtení, ale roura je pořád otevřena, vrátí funkce read chybovou návratovou hodnotu (-1) a errno nastaví na EAGAIN
  • pro ověření, zda jsou data připravena pro zápis/čtení je vhodné používat nějakou funkci, například select
FD_ZERO(&rfds);
FD_SET(rpipe_fd,&rfds);
 
FD_ZERO(&wfds);
FD_SET(wpipe_fd,&wfds);
 
if (select(nfds, &rfds, &wfds, NULL, &tv) == -1) {
  fprintf(stderr,"pipe error %d\n", errno);
}
 
if (FD_ISSET(rpipe_fd, &rfds)) {
..
// do reading
..
inter-process-comm.1461055709.txt.gz · Poslední úprava: (upraveno mimo DokuWiki)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki