[Haskell-cafe] named pipe interface
Jean-Marie Gaillourdet
jmg at gaillourdet.net
Mon Jan 16 09:38:08 CET 2012
Hi,
On 14.01.2012, at 12:11, Serge D. Mechveliani wrote:
> 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).
I'd say this use of unsafePerformIO is *not* safe. E.g. a Haskell compiler is allowed to evaluate the right hand side of toA and fromA multiple times. If you aren't 100% sure that it is ok to use unsafePerformIO, don't use it!
Try something like the following:
> initIO = do
> to <- toA_IO
> from <- fromA_IO
> return (to, from)
> axiomIO (to,from) str = do
> fdWrite to str
> (str, _len) <- fdRead from 64
> return str
> main = do
> fds <- initIO
> …
> res <- axiomIO fds "…"
Obviously I didn't compile and test this code.
> 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
>
>
>
> _______________________________________________
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users at haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
More information about the Haskell-Cafe
mailing list