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