Cteni z FIFO & vice procesu & fce select() [vyreseno]
Tomas Rollbach
troll na logix.cz
Neděle Leden 7 00:33:46 CET 2001
> To zalezi, jak to presne chcete pouzit. Nejjednodussi je zaridit, aby
> tam nikdo neposlal EOF. Anebo po zjisteni EOF rouru zavrit a znovu
> otevrit vsemi ctecimi procesy ...
Ale EOF je znak, ne? A ten tam nikdo neposila. Kdyz zavolam
write(fd, "ABC", 3)
tak write vrati 3 a tst.c (i kdyz ho spustim jednou) po precteni 'C' a
zavreni 'fd' projede 7x ten cyklus s vysledkem "no char". Takze ke cteni
neni nic a select() to presto pusti.
> Anebo muzete zcela predelat design aplikace. Pokud trvate na FIFO, tak
> nechte jeden hlavni proces cist znaky z FIFO a predavat je do do
> fronty zprav (IPC messages) a nechte ty procesy, co ty znaky
> zpracovavaji, cist z te fronty zprav.
To nepomuze, protoze i kdyz je cteci proces jen jeden, tak to nebeha podle
mych predstav. Chtel jsem, aby to fungovalo naslednovne:
1) proces A otevre rouru pro cteni
2) proces B otevre pro zapis, neco zapise a uzavre
3) proces A to neco precte a zpracuje a _ceka_dal_ ?
Procesu A muze byt celkem hodne a ziji dlouho, procesu B muze byt take
hodne, ale FIFO maji otevreno jen kratce.
Zatim jsem to vyresil tak, ze proces A rouru otevre ne O_RDONLY, ale
O_RDWR a chodi to. Vypada to, ze roura vzdy musi byt otevrena pro
zapis, aby byla nadeje, ze tam nekdo neco posle. Jinak se na to
select() vybodne a vzdycky to pusti.
Doufam, ze je to dostatecne "ciste" reseni...
Tomas Rollbach
-- troll
> > tst.c:
> > int main()
> > {
> > int fd, pid, cnt, retval, i;
> > fd_set rfds;
> > char c;
> >
> > fd=open("tst.fifo", O_NONBLOCK|O_RDONLY);
> > if(fd<0) { printf("%s\n", strerror(errno)); return -1; }
> >
> > pid=getpid();
> > printf("PID: %d\n", pid);
> >
> > for(i=0; i<10; i++)
> > {
> > FD_ZERO(&rfds);
> > FD_SET(fd, &rfds);
> > retval = select(fd+1, &rfds, NULL, NULL, NULL);
> > if(retval)
> > {
> > cnt=read(fd, &c, 1);
> > if(cnt==0) printf("%d: no char\n", pid);
> > if(cnt<0) printf("%d: %s\n", pid, strerror(errno));
> > if(cnt>0) printf("%d: %c\n", pid, c);
> > }
> > }
> > return 0;
> > }
> >
Další informace o konferenci Linux