URL: https://linuxfr.org/forums/programmation-c--2/posts/probl%C3%A8me-avec-select-et-pipe Title: Problème avec select et pipe Authors: Moonz Date: 2010年03月10日T11:12:05+01:00 Tags: Score: 1 Bonjour à tous, Pour un de mes projets, j’ai eu à faire communiquer deux programmes à l’aide d’un pipe. Rien de bien sorcier. Puis, j’ai eu besoin de gérer le timeout. J’ai tenté de le faire avec select (toujours rien de magique), et à ma grande surprise... ça ne fonctionne pas ! Voici mon code, simplifié le plus possible. C’est une utilisation basique de select(), et je ne vois pas comment j’ai pu me planter là dedans. Si quelqu’un arrive à trouver, il me permettra d’assouvir ma curiosité et donc de dormir cette nuit ;) #include #include #include #include #include static int rd_fd, wr_fd; void phy_send_byte(uint8_t b) { £spaces£ £/spaces£if(write(wr_fd, &b, 1) < 0) { £spaces£ £/spaces£perror("phy_send_byte"); £spaces£ £/spaces£exit(1); £spaces£ £/spaces£} } uint8_t phy_recv_byte(int timeout, int *timed_out) { £spaces£ £/spaces£uint8_t b; £spaces£ £/spaces£fd_set wait_fds; £spaces£ £/spaces£struct timeval sel_timeout = {.tv_sec = timeout, .tv_usec = 0}; £spaces£ £/spaces£ £spaces£ £/spaces£FD_ZERO(&wait_fds); £spaces£ £/spaces£FD_SET(rd_fd, &wait_fds); £spaces£ £/spaces£ £spaces£ £/spaces£if(select(1, &wait_fds, NULL, NULL, &sel_timeout) == 0) { £spaces£ £/spaces£if(timed_out != NULL) £spaces£ £/spaces£*timed_out = 1; £spaces£ £/spaces£return b; £spaces£ £/spaces£} £spaces£ £/spaces£ £spaces£ £/spaces£if(read(rd_fd, &b, 1) < 0) { £spaces£ £/spaces£perror("phy_recv_byte"); £spaces£ £/spaces£exit(1); £spaces£ £/spaces£} £spaces£ £/spaces£ £spaces£ £/spaces£if(timed_out) £spaces£ £/spaces£*timed_out = 0; £spaces£ £/spaces£ £spaces£ £/spaces£return b; } int main(int argc, char **argv) { £spaces£ £/spaces£int server_pipe[2]; £spaces£ £/spaces£int timed_out; £spaces£ £/spaces£ £spaces£ £/spaces£pipe(server_pipe); £spaces£ £/spaces£ £spaces£ £/spaces£if(fork() == 0) { £spaces£ £/spaces£rd_fd = server_pipe[0]; £spaces£ £/spaces£fprintf(stderr, ">>> %x\n", phy_recv_byte(5, &timed_out)); £spaces£ £/spaces£} £spaces£ £/spaces£else { £spaces£ £/spaces£wr_fd = server_pipe[1]; £spaces£ £/spaces£phy_send_byte(42); £spaces£ £/spaces£fprintf(stderr, "<<< %x\n", 42); £spaces£ £/spaces£wait(NULL); £spaces£ £/spaces£} £spaces£ £/spaces£return 0; } Si vous lancez le programme, vous remarquerez que le select() finit en timeout, comme si aucune donnée n’était reçue. Mais si vous commentez le select(), le read() renvoie les données ! Plus étrange encore, si je remplace le select() par poll(), ça fonctionne comme un charme. £spaces£ £/spaces£struct pollfd pfd; £spaces£ £/spaces£ £spaces£ £/spaces£if(timeout <= 0) £spaces£ £/spaces£timeout = -1; £spaces£ £/spaces£pfd.fd = rd_fd; £spaces£ £/spaces£pfd.events = POLLIN; £spaces£ £/spaces£if(poll(&pfd, 1, timeout) == 0) { £spaces£ £/spaces£if(timed_out != NULL) £spaces£ £/spaces£*timed_out = 1; £spaces£ £/spaces£return b; £spaces£ £/spaces£} Je ne cherche pas tant la solution qu’une explication... Merci à tous ceux qui feront avancer l’enquête !

AltStyle によって変換されたページ (->オリジナル) /