in reply to Re^2: Thoughts on how to devise a queryable win32 service
in thread Thoughts on how to devise a queryable win32 service
You had me going there for a few seconds--everything in your program seemed legit at first glance;
Problems:
The Thread module relates to an early attempt at threading in Perl (called perl5005threads). These were deemed a failure and are "going away" in the next release.
It has been superceded by Ithreads via the threads module.
It requires at least 5.7.?, but you should not try to use them with any version < 5.8.4 -- get 5.8.6 if you can.
In (my) reality, if you are running in a single CPU machine, read references do not appear to need locks be applied as only one thread can be running at a time, but if you move the code without locks to a multiprocessor machine you would likely get bitten.
In theory, even on a single processor machine, it is possible that one thread could be in the process of writing to a shared variable and have not completed the update when it gets suspended. If it did not apply locks, or another thread reading it does not apply them (and thereby get suspended until teh write is completed), then the other thread could read a partially updated variable that is not in an internally coherent state and get bad data or even segfault.
To date, try as hard as I might, even running long running, backtracking regexes on huge shared strings, I have never been able to make this happen.
( For the pedantic: The above statement is only true: on my single processor, win32 machine; in my house; whilst I've been watching; etc. etc. etc.....Yet! ;)
use strict; use threads; use threads::shared; my $time : shared; sub listener { my $array_ref = shift; while (1) { { lock $time; print "\tThread time: [$time]\n"; } { lock($array_ref); print "\tThread time: [@$array_ref]\n"; } sleep 3; } } my @array : shared; my $t = threads->new( \&listener, \@array ); while (1) { { lock $time; $time = localtime; } print $time,"\n"; { lock @array; push @array, $time; } sleep 1; } __END__ [16:09:17.53] P:\test>429405 Wed Feb 9 16:09:31 2005 Thread time: [Wed Feb 9 16:09:31 2005] Thread time: [] Wed Feb 9 16:09:32 2005 Wed Feb 9 16:09:33 2005 Thread time: [Wed Feb 9 16:09:33 2005] Thread time: [Wed Feb 9 16:09:31 2005 Wed Feb 9 16:09:32 200 +5 Wed Feb 9 16:09:33 2005] Wed Feb 9 16:09:34 2005 Wed Feb 9 16:09:35 2005 Wed Feb 9 16:09:36 2005 Terminating on signal SIGINT(2)
I switched your code around a bit not because there was anything wrong with the ordering, but to allow me to demonstrate a couple of points.
I've stopped passing the scalar ref to the sub and am passing a reference to an array that is also updated in the main thread.
Because $time is visible to your listener() sub, it is accessible, via closure in the normal way, without being explicitly passed it to the thread.
The array however, was not existing when the sub was declared, so it must be passed explicitly.
Basically, all the normal perl scoping rules apply--once you are using the correct modules :) I should have mentioned that before. Sorry!
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^4: Thoughts on how to devise a queryable win32 service
by noslenj123 (Scribe) on Feb 10, 2005 at 00:10 UTC | |
|
Re: point #4
by Anonymous Monk on Feb 10, 2005 at 00:10 UTC | |
by BrowserUk (Patriarch) on Feb 10, 2005 at 07:53 UTC | |
by perlhaq (Scribe) on Feb 10, 2005 at 16:33 UTC | |
by BrowserUk (Patriarch) on Feb 10, 2005 at 17:47 UTC |