2009/1/23 Ertugrul Soeylemez <e...@ertes.de>: > Luke Palmer <lrpal...@gmail.com> wrote: > >> On Thu, Jan 22, 2009 at 9:04 AM, Ertugrul Soeylemez <e...@ertes.de> wrote: >> >> > Sometimes this is inevitable, but I've never seen a case, where >> > IORefs couldn't be replaced by a more elegant State/StateT-based >> > solution. And if you need to do multi-threading, Chans, MVars and >> > semaphores are better anyway. >> >> Please define "better". For the function in question, what advantages >> do they give us? > > It gives you thread-safety for free, which IORefs don't give you. It's > the same purpose, the same amount of code, but threadsafe by concept. > Of course, for simple variables, IORefs will likely be thread-safe as > well, but there is no guarantee here. With MVars you have that > guarantee. > > >> Just to be clear, I wouldn't dare argue that IORefs can do everything >> MVars and TVars can do. I'm just perplexed why you say MVars and >> TVars are better, when an IORef does the trick just fine for our >> function. > > What I'm saying is: Even if IORefs suffice, why would you want to use > them, if MVar does the job as well and likely better? > > >> > There is no reason to prefer an IORef over an MVar to signal >> > something to another thread. >> >> Well, I usually don't go here, but benchmarks show that IORefs are the >> fastest of any of the mutable variable primitives, by at least a >> factor of 2. I wish I remembered where I saw that. > > Yes, that's a good point, but I think, you can safely disregard that for > signalling a thread to quit. > > >> > By the way, IORefs are by themselves not thread-safe. You need to >> > use a special function, when using it in a multi-threaded manner. >> >> You mean atomicModifyIORef? > > Yes. > > >> IORefs *are* thread-safe by themselves: you will not make your program >> segfault by using them in a multithreaded program. So it all comes >> down to invariants. IORefs have no synchronization concepts, so code >> like: >> >> x <- readIORef ref >> writeIORef ref (x+1) >> >> Is not threadsafe by most standards. That doesn't mean IORefs >> themselves are not threadsafe, just that you have to be careful how >> you use them. > > That's exactly my point. In the above case they do just the same, but > need more care. > > >> And I will reiterate: *in this case* the use of IORef is fully >> encapsulated in this function and *is threadsafe!* Which is the basis >> of my argument: in imperative code, when you can limit the scope of an >> IORef to a small abstraction that is threadsafe, there is no advantage >> of TVars or MVars over them. I don't think they deserve "bad style" >> sledgehammer. (An instance of "use the right tool for the job") >> >> daemon :: IO () -> IO (IO ()) >> daemon action = do >> stopvar <- newIORef False >> let run = do >> stop <- readIORef stopvar >> if stop then return () else (action >> run) >> forkIO run >> return (writeIORef stopvar True) > > In this case, it's simply a coincidence that it's safe. It's because > you're using an IORef Bool, and because writes to a Bool variable are > atomic on virtually all platforms. An Integer may already fail to be > thread-safe. You need more care and the payoff is zero. If you still > insist on using IORefs, at least use the atomic function above, but that > destroys the little performance benefit of using IORefs, unless GHC does > some intelligent optimization here, which I doubt.
This would be the case if the IORef was unboxed, but it is boxed, so writing an IORef is actually writing a pointer to a thunk; here, Bool and Integer have no difference at all. However, I don't know whether GHC makes pointer writes atomic on all platforms (Java does, so it's at least doable). > > > Greets, > Ertugrul. > > > -- > nightmare = unsafePerformIO (getWrongWife >>= sex) > http://blog.ertes.de/ > > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe