[Haskell-cafe] named pipe interface

Serge D. Mechveliani mechvel at botik.ru
Sat Jan 14 12:11:52 CET 2012


On Fri, Jan 13, 2012 at 12:19:34PM -0800, Donn Cave wrote:
> Quoth "Serge D. Mechveliani" <mechvel at botik.ru>,
> ...
> > Initially, I did the example by the Foreign Function Interface for C.
> > But then, I thought "But this is unnatural! Use plainly the standard
> > Haskell IO, it has everything".
> >
> > So, your advice is "return to FFI" ?
> 
> Well, it turns out that the I/O system functions in System.Posix.IO
> may work for your purposes.  I was able to get your example to work
> with these functions, which correspond to open(2), read(2), write(2).
> 
> I would also use these functions in C, as you did in your C program.
> Haskell I/O functions like hGetLine are analogous to C library I/O
> like fgets(3) - in particular, they're buffered, and I would guess
> that's why they don't work for you here.
> 
> Specifically,
>    openFile "toA" WriteOnly Nothing defaultFileFlags
>    openFile "fromA" ReadOnly Nothing defaultFileFlags
> 
>    fdWrite toA str
>    (str, len) <- fdRead fromA 64
>    return str


Great! Thank you very much.
As I find,  Posix.IO  is not of the standard, but it is of GHC.
Anyway, it fits my purpose.
By  openFile  you, probably, mean  openFd.

Another point is the number of open files, for a long loop.
I put
  toA_IO   = openFd "toA"   WriteOnly Nothing defaultFileFlags
  fromA_IO = openFd "fromA" ReadOnly  Nothing defaultFileFlags

  axiomIO :: String -> IO String
  axiomIO str = do
                toA   <- toA_IO   
                fromA <- fromA_IO
                fdWrite toA str
                (str, _len) <- fdRead fromA 64
                return str

When applying  axiomIO  in a loop of 9000 strings, it breaks:
"too many open files".
I do not understand why it is so, because  toA_IO and fromA_IO  are 
global constants (I have not any experience with `do').

Anyway, I have changed this to

  toA   = unsafePerformIO toA_IO
  fromA = unsafePerformIO fromA_IO
  axiomIO :: String -> IO String
  axiomIO str = do
                fdWrite toA str
                (str, _len) <- fdRead fromA 64
                return str

And now, it works in loong loops too
(I need to understand further whether my usage of  unsafePerformIO  
really damages the project).
Its performance is  9/10  of the  C <-> C  performance 
(ghc -O, gcc -O, Linux Debian). 
It is still slow:  120000 small strings/second on a 2 GHz machine.
But this is something to start with.

>  I was able to get your example to work
> with these functions, which correspond to open(2), read(2), write(2).
>
> I would also use these functions in C, as you did in your C program.
> Haskell I/O functions like hGetLine are analogous to C library I/O
> like fgets(3) - in particular, they're buffered, and I would guess
> that's why they don't work for you here.

Indeed. Initially, I tried  C <-> C,  and used  fgets, fputs, fflush.
And it did not work, it required to open/close files inside a loop;
I failed with attempts. Again, do not understand, why (do they wait
till the buffer is full?).

Then, I tried  read/write,  as it is in  fifoFromA.c  which I posted.
And it works.
Now,  Haskell <-> C  gives a hope. Nice.

Thanks,

------
Sergei
mechvel at botik.ru





More information about the Haskell-Cafe mailing list