Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Back to the Future of Threads (Part II)

by AgentM (Curate)
on Oct 21, 2000 at 13:28 UTC ( [id://37796]=perlmeditation: print w/replies, xml ) Need Help??

use Threads; is labeled as experimental in perl5. (Hopefully this will be taken care of in Perl6.) Experimental means to me "beware", "use with caution", or "still in development". It never means "evil" or "to be always avoided". I simply decided to experiment with an "experimental" feature. These are my results.

The actual goal of my self-defined self-assigned project was to test and solve the problem of threads in perl 5. The current problem is very vaguely described by merlyn and Ovid and is very possibly transparent to programmers not very familiar with thread entity programming. What the problem is:
  • race conditions are not properly handled with the perlthreads lock mechanism since they are neither hardware nor kernel calls. perlthreads was designed to be fully platform independent which means that perlthreads are implemented within perl itself and does not involve kernel/ hardware calls. The problem is that without such calls, mission-critical functions like mutex locks (discussed later) become interruptable (by signals or on error, for example). This is usually fatal to the algorithm if not to the program. The mutex lock is supposed to lock the data's access which is supposed to be implemented in the kernel with hardware enhancement in the memory model (such as in the cache). Unfortunately, Perl 5 threads do not incorporate any such enhancements and thus are unable to function properly. What one ends up with is a mutex with a race condition which can only lead to fatal errors.
  • Perl threads are implemented in the perl layer, which means they will never attain the performance of OS level threads. They are a psuedo-type of threads, like those old DEC threads.
  • Perl threads offer very poor thread communication. Pthreads support mutexes, condition vars, and various types of realtime scheduling. Perl threads are new and support only a primitive form of a mutex.

But I still insisted on using threads with Perl. It dawned on me that i would not find the solution within perl itself but within the plausible C/perl combinations. Perl's tar ball includes perlxs, which allows one to compile C into usable perl modules or other forms of cross-linkable objects. I thought about using perlxs but realized quickly that that would not solve my problem since converting variables back and forth between C and Perl and then locking pointers that must be created....blah,blah,blah would be not only extremely complicated but the race conditions may still come up in between interruptable c wrappers in the perl script itself. Boooo!

The final solution involved the reversal of C imbedded in perl- perlembed! Using two nifty libraries that come standard in the perl distro, one is able to embed one or multiple perl interpreters in any given C program. This is phenomenal not just for threads but other stuff exclusive to perl such as regexes (in C!). I recommend that every C programmer looks into this... Anyway, I realized that if I wrapped my perl in C code using, I could run multiple interpreters (one per thread), then using C mutexes, I could safely lock variables and read/write/convert variables in C and in Perl. In addition, I would able to use Pthread interfaces, effective interthread communication, and use Perl for everythin or anything else! While this may seem elementary to some, it took me (as you see) quite some time to come across. Just to show some code, I came up with a program that uses "threaded perl"- really it just processes the perl command line twice simultaneously. Yes, I already anticipate the responses- 'that's not threaded Perl, that's threaded C!' Sure this is also true, but my goal (above) was to come up with a way to use threads and perl at the same time. Perl.h makes it possible! I will be using similar code like below in many servers that i will write (since servers ARE better multi-threaded).

#include <EXTERN.h> #include <pthread.h> #include <perl.h> void perlthread(void*); char *gargv[]; //quick hack for function- global vars int gargc; int main(char *argv[], int argc) { PerlInterpreter * perl1, *perl2=NULL; if((perl1=perl_alloc())==NULL) errormsg(); perl_construct(perl1); gargc=argc; gargv=argv; //initialize second perl interpreter...etc. status1=pthread_create(&amp;tid1,NULL,perlthread,perl1); status2=pthread_create(&amp;tid2,NULL,perlthread,perl2); pthread_join(tid1,NULL); pthread_join(tid2,NULL); perl_destruct(perl); perl_free(perl); } void perlthread(void *arg) { perl_parse(arg,NULL,gargc,gargv,NULL); }
Even if you initiate multiple instances of the interpreter, you can process and exchange variables in both instances by initializing the perl interpreter and friends in shared memory (along with shared C mutex and condition vars). Be warned though, functions in the library such as perl_call_argv are not thread-safe and MUST be avoided in threaded circumstances. Instead, it's appropriate to keep the code in a separate file to be parsed with perl_parse() as described in perlembed. You may also be interested in perlxstut, which wil teach you how to embed C in Perl (not directly, but using a separate compiler command...)

Perhaps none of the above discussion applies to your current programming practice. In that case, I urge you to sift through C/Perl XS and integration tutorials. If you ever need something as simple in a regex in C, perlembed is as real lifesaver! I just thought it might be interesting to find out who else has been toying with "subPerl" coding and what they've done. I haven't seen it mentioned except by faq_monk so I thought I'd bring it up and my threads idea gave me the perfect chance!

Here's one of my favorite lines from perlembed:

MORAL

You can sometimes write faster code in C, but you can always write code faster in Perl. Because you can use each from the other, combine them as you wish.

AgentM Systems nor Nasca Enterprises nor Bone::Easy nor Macperl is responsible for the comments made by AgentM. Remember, you can build any logical system with NOR.

Replies are listed 'Best First'.
RE (tilly) 1: Back to the Future of Threads (Part II)
by tilly (Archbishop) on Oct 21, 2000 at 18:58 UTC
    Before you start using this in production you may want to glance at this email for a few useful tips and tricks. There are a few other discussions of this on p5p. But with the current state of Perl I have to say that is certainly the best way to do multi-threaded stuff with Perl.

    Oh, and Sarathy might like hearing about whatever you are doing, as he said he likes knowing that he isn't the only person doing this kind of stuff. :-)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://37796]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (4)
As of 2024-04-19 22:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found