Re: OO and Threads conflict?
by RMGir (Prior) on Sep 21, 2002 at 10:47 UTC
|
# note the package level shared hash; this will store the
# actual values of the active attribute.
my %active : shared;
# CONSTRUCTOR
sub new {
local *IN;
my $self = {};
$self->{active} = \$active{$self} = 1; # This vari
+able must be shared between threads.
$self->{in} = undef;
$self->{thread} = undef;
open(*IN, "a_program" ) or ${$self->{active}} = 0;
$self->{in} = *IN;
$self->{thread} = threads->new(\&reader, $self); # Start thread
bless($self);
return $self;
}
Then you can access the shared value as ${$self->{active}}, or as $active{$self} if you're in the package...
At least, I think this will work; it would be nice if I had 5.8.0 installed here to test it :)
--
Mike | [reply] [d/l] |
Re: OO and Threads conflict?
by Anonymous Monk on Sep 20, 2002 at 23:29 UTC
|
To clarify, I am showing an example of what I am trying to do, trimmed down and not functional. As you can see, it's a simple object with a separate thread that keeps reading the output from a program. The thread should exit when the variable $self->{active} turns false, for example by running the method 'stop'.
package Thingee;
use threads;
use threads::shared;
# CONSTRUCTOR
sub new {
local *IN;
my $self = {};
$self->{active} : shared = 1; # SYNTAX ERROR HERE
# This variable must be shared between
# threads.
$self->{in} = undef;
$self->{thread} = undef;
open(*IN, "a_program" ) or $self->{active} = 0;
$self->{in} = *IN;
$self->{thread} = threads->new(\&reader, $self); # Start thread
bless($self);
return $self;
}
# READER (Thread)
sub reader {
my $self = shift;
my $fh = $self->{in};
my $line;
while ( $self->{active} ) {
$line = <$fh>;
print "> $line\n";
}
}
# METHOD
sub stop {
my $self = shift;
$self->{active} = 0;
}
# RETURN TRUE FOR THE USE
1;
| [reply] [d/l] |
Re: OO and Threads conflict?
by runrig (Abbot) on Sep 20, 2002 at 23:59 UTC
|
However, when using objects... This doesn't work:
$self->{var} : shared = 1;
Consider me a threading newbie, but is there any reason you can't just share "$self". Or maybe this: my $self = {};
my $var : shared = 1;
$self->{var} = \$var;
#(Update)Then later to get or set $var:
${$self->{var}} = 0;
...
while (${$self->{var}) {
...
| [reply] [d/l] [select] |
|
|
Yes. Trying to share $self as such;
my $self : shared = {};
results in an error:
Invalid value for shared scalar at...
As for the suggested code snippet, I still end up with the thread having it's own private copy of the $self->{var}. The main thread and the 'loose thread' still do not share any data.
| [reply] [d/l] [select] |
|
|
| [reply] |
|
|
Gee... Thanks. =)
When referring to them as ${$self->{var}] it DOES work. The problem is now officially solved. Now, would you please explain to me what you did, because I am feeling abit lost here. =)
And... This doesn't mean that the data is shared between all instances off the class, right?
| [reply] |
|
|
Re: OO and Threads conflict?
by djantzen (Priest) on Sep 20, 2002 at 22:06 UTC
|
I'd hazard a guess that it's the difference between sharing a variable and sharing a value, where in the former case you've actually got a label by which to refer to a thing and in the latter you're doing a hash lookup and returning a string or integer or something. Does it work if you say
$self->{var} = $var; $self->{var} : shared = 1; ?
| [reply] [d/l] |
|
|
Nope...
$self->{var} : shared = 1; gives a syntax error. Doesn't matter what you write before it. It's still a syntax error.
| [reply] [d/l] |
|
|
What about declaring the variable shared before assigning it to your hash, as in my $var : shared = 1; $self->{var} = \$var. Although on further consideration I wonder if it might be better to be using a package variable via our or use vars since it looks like what you want is a 'static' variable i.e., one shared by all instances of a class, and these constructs provide that behavior. I don't have threads compiled so I can't test this, but this might work:
package OOThread;
use threads;
our static_var : shared = 1; # may not be necessary to explicitly shar
+e 'our' variables
sub new {...}
...
| [reply] [d/l] [select] |
|
|
Re: OO and Threads conflict?
by beamsack (Scribe) on Sep 21, 2002 at 18:55 UTC
|
I am betting that every thread created in this example already shares a variable with the main thread - the object itself!
$self->{thread} = threads->new(\&reader, $self); # Start thread
- The object starts the thread, passing function reader as parameter 1 - the thread proc
- $self (i.e. the object) is passed as parameter 2
Therefore any functionality of the object should be available to the thread.I think the concept of wrapping threads in objects is a little confusing and dangerous. A thread proc is different than a object function - it represents a new path of execution. It may be cool to wrap a thread in an object but objects go out scope - $self will become invalid if the object goes out scope before thread function reader exits. | [reply] [d/l] |
|
|
| [reply] |
|
|
Thanks Aristotle I will look into closures. I usually test my assumptions but I'm stuck working today. I have spent too many years chasing down pointer problems in C/C++ - this is for sure, point taken. I am making a dangerous assumption that the function reader is equivalent to a thread proc in C/C++. If so, it is basically just like the main() function in C. It will need to return before dying. If I pass an object into a thread proc that some how controls the life-time of the thread, I hope that the object's life-time exceeds that of the thread. If the object ceases to exist before the thread terminates - how will I control the thread. Threads can cause wickedly interesting problems!!!
| [reply] |
|
|