View Full Version : Select() Posix: grattacapo
LimiT-MaTz
20-12-2006, 21:03
#include <stdio.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
int fd = 0;
char * value= (char *) malloc (sizeof(char) * 100);
int retval;
int len = 0;
fd_set rfds;
fd = open("/home/matz/fifo", O_RDONLY);
for(;;){
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
retval = select(fd + 1 , &rfds, NULL, NULL, NULL);
printf("retval %d\n",retval);
if (retval == -1) {
fprintf(stderr, "select failed:");
return -1;
}
else{
if (FD_ISSET(fd, &rfds)) {
len = read(fd, value, 100);
value[len]='\0';
printf("%s",value);
}
}
}
return 0;
}
/* dopo aver letto per la prima volta un dato dalla fifo ad ogni ciclo successivo continua a vedere retval = 1 e il fd registrato nell'insieme rfds */
/home/matz/fifo è una fifo.
Lancio il programmino lui entra nella select e rimane in attesa.
Un altro processo scrive sulla fifo a questo punto il "programmino" si sveglia e stampa su stdout il dato.
Fin qui tutto ok.
Ora vengono i problemi:
rinizia il ciclo riazzero l'insieme rfds inserisco fd nell'insieme entro nella select ma NON MI FERMO (nessun processo ci ha scritto sopra).
Non riesco a capire perchè cio' accada ...
Sapreste aiutarmi?
ilsensine
21-12-2006, 09:10
Hai raggiunto una condizione di EOF; puoi controllare che la read ritorna 0.
Fatti un favore, uccidi la select e usa la poll.
LimiT-MaTz
21-12-2006, 11:10
ok, accetto il tuo consiglio per quanto riguarda la poll.
int main()
{
int fd = 0;
char * value= (char *) malloc (sizeof(char) * 100);
int retval;
int len = 0;
struct pollfd p;
fd = open("/home/matz/fifo", O_RDONLY);
for(;;){
p.fd = fd;
p.events = POLLIN;
retval = poll(&p, 1, 0);
printf("retval %d\n",retval);
if (retval == -1) {
fprintf(stderr, "select failed:");
return -1;
}
else{
if(p.revents == POLLIN)
{
printf("HERE");
len = read(fd, value, 100);
value[len]='\0';
printf("%s",value);
}
}
}
return 0;
}
in output avro':
HERE
"dato ricevuto"
retval 1
retval 1
retval 1
retval 1
se vado a controllare p.revents è != da POLLIN, cio' nonostante poll() ritorna 1, nonostante in events abbia specificato solo POLLIN.
questo nn mi torna:
RETURN VALUE
On success, a positive number is returned; this is the number of structures which have non-zero revents fields (in other words, those
descriptors with events or errors reported). A value of 0 indicates that the call timed out and no file descriptors were ready. On
error, -1 is returned, and errno is set appropriately.
ilsensine
21-12-2006, 11:18
Torna, torna. Il pipe è stato chiuso dall'altro lato, e revents ritorna l'evento come POLLHUP. Gli eventi di errore vengono _sempre_ ritornati, anche se non li hai richiesti.
LimiT-MaTz
21-12-2006, 11:45
la situazione diventa problematica...
ti spiego quello che volevo fare:
un processo multitread che ascoltasse i comandi sulla pipe e in base a questi facesse delle operazioni.
La mia idea era quella di usare una fifo e leggere da questa quando si presentavano dei dati usando appunto un meccanismo (select).
Visti gli sviluppi ora non so come comportarmi.
ilsensine
21-12-2006, 12:05
Semplicemente, chiudi e riapri la pipe.
LimiT-MaTz
21-12-2006, 13:00
Semplicemente, chiudi e riapri la pipe.
argh, non ci sono ancora...
int main()
{
int fd = 0;
char * value= (char *) malloc (sizeof(char) * 100);
int retval;
int len = 0;
struct pollfd p;
fd = open("/home/matz/fifo", O_RDONLY);
for(;;){
p.fd = fd;
p.events = POLLIN;
retval = poll(&p, 1, 0);
printf("retval %d\n",retval);
if (retval == -1) {
fprintf(stderr, "select failed:");
return -1;
}
else{
if(p.revents == POLLIN){
printf("POLLIN\n");
len = read(fd, value, 100);
value[len]='\0';
printf("%s\n",value);
}
if(p.revents == POLLHUP){
printf("POLLHUP");
close(fd);
open("/home/matz/fifo", O_RDONLY);
}
}
}
return 0;
}
nulla da fare casualmente ogni tanto si looppa e spara in stdout una serie di retval 1.
ilsensine
21-12-2006, 14:46
Che casotto che hai fatto...
int main()
{
int fd;
char * value= malloc (sizeof(char) * 100);
int retval;
int len;
struct pollfd p;
p.events = POLLIN;
fd = open("/home/matz/fifo", O_RDONLY);
while(fd>=0){
p.fd = fd;
retval = poll(&p, 1, -1);
printf("retval %d\n",retval);
if (retval == -1) {
perror("poll");
return -1;
}
if(p.revents & POLLIN){
printf("POLLIN\n");
len = read(fd, value, 99);
if (len>=0) {
value[len]='\0';
printf("%s\n",value);
} else
perror("read");
} else if(p.revents & POLLHUP){
printf("POLLHUP\n");
close(fd);
fd = open("/home/matz/fifo", O_RDONLY);
}
}
perror("open");
return -1;
}
LimiT-MaTz
21-12-2006, 14:53
effettivamente ... :muro:
Grazie come al solito sei stato gentilissimo!
ilsensine
21-12-2006, 15:21
Volendo essere pignoli, c'è ancora un "piccolo" errore:
if (retval == -1) {
if (errno!=EINTR) {
perror("poll");
return -1;
}
continue;
}
La poll ritorna EINTR anche in corrispondenza di SIGSTOP+SIGCONT :muro:
trallallero
22-12-2006, 10:34
Fatti un favore, uccidi la select e usa la poll.
perché ? io l'ho usata per un progetto per la EdisonTel (2001) e sta ancora andando da quello che so
ilsensine
22-12-2006, 12:00
perché ?
Poco scalabile; interfaccia dubbia (limite di FD_SETSIZE "hardcoded" all'atto della compilazione).
La poll è pià semplice e compatta, e non è legata a quell'assurda idea degli FD_SET.
trallallero
22-12-2006, 12:48
Poco scalabile; interfaccia dubbia (limite di FD_SETSIZE "hardcoded" all'atto della compilazione).
La poll è pià semplice e compatta, e non è legata a quell'assurda idea degli FD_SET.
ero convinto di aver usato la select ma in effetti non c'entra niente :stordita:
Ho rivisto il codice, ho usato socket, accept, setsockopt...
Uff, non mi ricordo neanche piú questa roba a furia di pro*ciare e di burocrazia aziendale :muro:
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.