in reply to Re^2: Passing globs between threads
in thread Passing globs between threads
The first thing to realise is that raw filehandles and sockets are process global. So you don't need, and indeed cannot, share them between threads in the threads::shared sense, as they are effectively already shared by all threads in the process.
Note: I'm talking about the OS & C-runtime concept of filehandles and sockets, not anything in the IO::* group of modules. These are peculiar beasts in that they are at some level like ordinary perl objects, which makes them difficult, if not impossible to use safely across threads, but they do not behave entirely like ordinary objects.
So, the problem is how to transfer an open handle between threads (which at a higher level seems like a bad design to me, but I'll get back to that), given that threads::shared won't let you share a GLOB nor even a 5.8.x lexical scalar that is currently being used as a GLOB-like entity.
After a little kicking around, I found a way. I'm not yet sure that it is a good thing to do, but I'll show you how anyway and hope that if someone else out there knows why it should not be done, they'll speak up.
The trick is to pass the fileno of the open GLOB to the thread and then use the special form of open open FH, "&=$fileno" or die $! to re-open the handle within the thread before using it.
#! perl -slw use strict; use IO::File; use threads; use Thread::Queue; sub thread{ my $Q = shift; my $fno = $Q->dequeue; open FH, "<&=$fno" or die $!; print for <FH>; return; } my $Q = new Thread::Queue; my $thread = threads->create( \&thread, $Q ); my $io = IO::File->new( 'junk', 'r' ) or die $!; $Q->enqueue( fileno $io ); $thread->join; $io->close; __END__ P:\test>395373 This is junk and some more junk and yet more junk this is line 4 of junk
However, this is not a complete solution. Currently, probably because of a bug I think, but possibly by design, if you actually read from the handle in the thread where you opened it, then pass the fileno to another thread, reopen it and attempt to read some more from it, it fails. No errors, no warnings. Just no input.
I've read and re-read perlfunc:open and perlopentut:Re-Opening-Files-(dups) , and I believe that the "&=$fileno" syntax should allow this...but it doesn't. If you need to be able to do this, you'll need to take it up with p5p guys and get their wisdom.
Now, getting back to design. Whilst moving objects around between threads by freezing and thawing them is possible, it feels awefully hooky to me. Basically, if your design is done correctly, there should be no need to create duplicates of objects in different threads.
Doing so is opening yourself up to a world of greif.
These duplicate objects will be uncoordinated. Once you freeze an object, it is exactly that; frozen. Any subsequent changes you make will not be reflected in the copy that you reconstruct elsewhere. If it was trivial, or even if it was possible with a reasonable degree of difficulty to coordinate and synchronise objects across threads, Perl would do that for you. The fact that the clever guys that got iThreads this far did not step up to the plate and do this already, almost certainly means that you should not be trying to do this either.
The fact is that I appear to have done as much coding of(i)threads as anyone I am aware of, and I have yet to see a usefully iThreadable problem I couldn't (almost trivially) solve. And so far, I have never needed to share either objects (or IO handles) between threads.
But don't take my word for it. My knowledge only extends as far as I have tried to go. It would be good to see someone else pushing the boundaries of what's possible.
If you could describe the problem that you are trying to solve at the application level, I'd be most interested to take a look.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re^4: Passing globs between threads
by conrad (Beadle) on Oct 01, 2004 at 10:36 UTC | |
by BrowserUk (Patriarch) on Oct 02, 2004 at 06:17 UTC | |
Re^4: Passing globs between threads
by Anonymous Monk on Oct 01, 2004 at 20:09 UTC | |
by BrowserUk (Patriarch) on Oct 01, 2004 at 22:22 UTC | |
by Anonymous Monk on Oct 02, 2004 at 00:27 UTC | |
by BrowserUk (Patriarch) on Oct 02, 2004 at 04:56 UTC | |
by Anonymous Monk on Oct 08, 2004 at 17:19 UTC | |
|