[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 Glasgow-haskell-users
mailing list