Re: [sigc] Re: [gtkmm] libsigcx and gtkmm 2.4
- From: Daniel Elstner <daniel elstner gmx net>
- To: Martin Schulze <martin-ml hippogriff de>
- Cc: libsigcx-main lists sourceforge net, libsigc-list gnome org, Gtkmm List <gtkmm-list gnome org>
- Subject: Re: [sigc] Re: [gtkmm] libsigcx and gtkmm 2.4
- Date: Sun, 13 Jun 2004 16:33:45 +0200
Am So, den 13.06.2004 um 2:10 Uhr +0200 schrieb Martin Schulze:
> > Hmm std::string is a perfect example of an argument type that
> > requires
> > special handling.
> Why? The slot object is completely initialized before the dispatcher
> knows of it. Note that sigc::bind does not take arguments as references
> by default if this is where you are heading.
std::string can be implemented with reference counting, and the
libstdc++ shipped with GCC does exactly that.
> > Even if it does this you still need mutex locking to protect
> > the memory being shared (ensuring that event A happens after event B
> > is
> > not enough due to the way modern hardware works; you definitely need
> > memory barriers too).
> Why would you need memory barries? Thread A creates some objects,
> thread B (the dispatcher) uses them and destroys them afterwards.
> Of course, if you pass references around, you need to make sure that
> thread A doesn't manipulate the data while thread B is handling it,
Wrong! It's not that simple. Whenever two threads access the same
data, both have to acquire the same mutex for any access to it
whatsoever, be it reading or writing. The only situation where this
rule doesn't apply is if thread A creates the data before launching
thread B, and both threads never write to it again, or only thread B
does and thread A never accesses it at all.
I highly recommend reading Butenhof's Programming with POSIX Threads.
In particular, memorize Chapter 3.4 Memory visibility between threads.
Here's a table from that chapter:
Time Thread 1 Thread 2
t write "1" to address 1 (cache)
t+1 write "2" to address 2 (cache) read "0" from address 1
t+2 cache system flushes address 2
t+3 read "2" from address 2
t+4 cache system flushes address 1
The point here is that there are no guarantees about memory ordering
whatsoever. As it happens reading address 2 works by chance, but the
read from address 1 returns the wrong value despite the fact that the
read happens after the write was completed.
Usage of special instructions is required to guarantee ordering, called
"memory barriers". Locking/unlocking a mutex issues these instructions.
] [Thread Prev