There's more than one way to do things | |
PerlMonks |
5005threads -> ithreads (porting)by castaway (Parson) |
on Sep 28, 2003 at 15:59 UTC ( [id://294757]=perlmeditation: print w/replies, xml ) | Need Help?? |
Since I attempted several times to convert a script of mine from 5005threads to ithreads, and then to make it work optionally with both, I thought I'd share my experiences (and see if anyone has any improvements/ideas on my technique.) It's a largish script which has two threads. The main thread spawns off the second thread, which is essentially running a telnet connection, and then starts to loop waiting for input from the user. (Yup, its a telnet/mud client..). I had fun getting it to work originally, as I was not using any Thread::Queues (and now realise I should have been, would have saved me lots of hassle); so there were deadlock problems when the telnet thread wanted to write to the screen (via a Term::Screen object), and when the input thread needed to write to the telnet connection. (Anyone seeing this simple description would probably think its tailor made for Queues, but I was just learning thread programming at the time, and didnt see this simplicity, there appeared to be a lot more interfaces between the two.)
Anyway: This was using 'use threads; use threads::shared' - ie just testing on perl 5.8.0 with ithreads. My goal was to get it to work with both, depending on which was available. To check for threads support and version, just a is needed. So I changed my 'use's to 'require's, and lo, everything continued to work.. Until I realised I did need to share one variable, $CONNECT, which is set by either thread to indicate that the connection is to be closed (either because it was closed by the server, or by the user). I tried to share this variable, and managed to seg fault perl - the segfault was on the 'share($CONNECT);' line, without that, everything ran fine.. (Fun) liz then proceeded to tell me that 'require threads::shared' isn't an option, as it needs to be done at compile time. So I tried to stick my $Config tests and requires in a BEGIN block, to no avail (still segfaulted). Then I swapped 'require' for 'use', which seems to ignore the BEGIN block, and attempt to load both Thread and threads, and produces a list of 'sub redefined's. A temporary solution was to use an extra Thread::Queue object in which a '1' is enqueued if either thread wishes to indicate a close. Strangely enough, Thread::Queue also just works using shared arrays and condition signals, but continues to work, even without threads::shared. (Note: Aha, Thread::Queue 'use's threads::shared itself! Hmm..) *some testing and 5.8.1 later* This segfaults (5.8.0): Also if the $CONNECT is global, for some reason share() doesnt want to work. This doesnt segfault, but also doesnt appear to work:
5.8.1 says to the first: which is somewhat more helpful. Current solution: Which runs fine in both 5.8.0 and 5.8.1. Only difference being that 5.8.1 (release, rc4 and rc5), now segfaults upon exit, somewhere when trying to destroy a thread or threads ( gdb output from core: Fazit: How to make a script that runs with 5005threads, ithreads or none at all: .. and use Queues as much as possible.. :) C.
Back to
Meditations
|
|