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" <mech...@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 > mech...@botik.ru > > > > _______________________________________________ > Glasgow-haskell-users mailing list > glasgow-haskell-us...@haskell.org > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe