Elizabeth Mattijsen <[EMAIL PROTECTED]> writes:
>At 12:12 PM 8/11/02 +0100, Nick Ing-Simmons wrote:
>> >The Thread::Tie module is a proof-of-concept implementation of another
>> >approach to shared variables. Instead of having shared variables exist
>> >in all the threads from which they are accessible, shared variable exist
>> >as "normal", unshared variables in a seperate thread. Only a tied object
>> >exists in each thread from which the shared variable is accesible.
>>That is actually exactly what threads::shared is supposed to do as well.
>>The only difference being that the "separate thread" has a shadowy
>>existance
>
>Aha! So maybe there the "2 other threads were running" message is coming
>from, when you only started one other thread.
It is a posibility.
>Does this shadowy thread run
>always, even if you don't have threads::shared ?
I think threads::shared bootstrap calls it into being.
>
>
>> and the client threads assume its identity (briefly) to become
>>their own server - which was supposed to be an optimization :-(
>
>Maybe it is from a CPU point of view, but it definitely isn't from a memory
>point of view. Because now in an array each element will need to be tied
>to the shared magic.
It isn't quite that bad. When you do a FETCH the returned value gets
tie - it should be freed when all references to the FETCHed value
go out of scope.
>In my approach only the object to which the array is
>tied, contains shared elements. Inside the thread, the array is an array
>just like any other array. Which saves a lot on magic. Or am I mistaken
>in this?
As far as I can tell your approach and the one I was aiming at are
identical (aside from the showdow thread thing).
However as I am doing all the tie and FETCH/STORE etc. in XS code
it is easier to make mistakes.
>
>
>> >=item memory usage
>> >Shared variables in this approach are truly shared. The value of a variable
>> >only exists once in memory. This implementation also circumvents the memory
>> >leak that currently (threads::shared version 0.90) plagues any shared array
>> >or shared hash access.
>>As the threads::shared scheme is _supposed_ to be exactly as you describe
>>there _should_ be no difference here.
>
>Apart from the huge memory leak that makes it impossible to use shared
>arrays and hashes in a production environment.
So let us find it.
>
>
>> >=item tieing shared variables
>> >Because the current implementation uses tie-ing, you can B<not> tie a shared
>> >variable. The same applies for this implementation you might say. However,
>> >it B<is> possible to specify a non-standard tie implementation for use
>> >B<within> the thread. So with this implementation you B<can> C<tie()> a
>> >shared variable. So you B<could> tie a shared hash to a DBM file à la
>> >dbmopen() with this module.
>>This is still an advantage of your scheme - as the server-thread is
>>"visible" its variable can be tied using normal approaches.
>
>Indeed. You can now have a shared filehandle that is tied using a module
>that doesn't know anything about threads. Such as a DBM file.
>
>I think the main disadvantages of Thread::Tie (at least under Linux) are:
>
>- threads->yield doesn't seem to yield.
>This means you're burning CPU needlessly until your timeslice is over.
ick - can we find something that _does_ yield?
>
>- a cond_wait, cond_signal pair is not guaranteed to pass the lock
>If you have a thread waiting at a cond_wait, and another thread is doing a
>cond_signal, the thread in cond_wait is _not_ guaranteed to get the lock()
>again. Not even if you're just using two threads! For example:
>
>Server thread:
>
> {lock( $shared );
> warn "server relinquishing control\n";
> cond_wait( $shared );
> warn "server in control again\n";
> }
>
>
>Client thread:
>
> {lock( $shared );
> warn "signalling server to act 1\n"
> cond_signal( $shared );
> }
> warn "unlocked 1, waiting for lock 2\n";
> {lock( $shared );
> warn "signalling server to act 2\n"
> cond_signal( $shared );
> }
> warn "unlocked 2\n";
>
>You will see that the client thread is able to gain the lock again after a
>cond_signal (about 75% of the time, under Linux, on my development box)
>before the server thread receives the signal.
You normally need a pair of semaphores to exchange requests between
a client and a server - but note that a "condition variable" is NOT
quite the same as a semaphore. Which is why higher level things like
queues are so popular.
>
>Because of this behaviour you need to have a seperate semaphore that is
>checked by the client to see whether the server actually received the
>(previous) signal before preceding. And of course, when the client sees
>that it gained the lock prematurely, you need to yield(). Something ugly like:
>
> my $tries;
> AGAIN: while (1) {
> threads->yield if $tries++;
> {lock( $control );
> next AGAIN if defined( $$control );
>
>And of course, at least under Linux, this eats CPU on a massive scale
>because yield() actually doesn't yield. ;-(
>
>
>Liz
--
Nick Ing-Simmons
http://www.ni-s.u-net.com/