forks - drop-in replacement for Perl threads using fork()
use forks; my $thread = threads->new( sub { # or ->create or async() print "Hello world from a thread\n"; } ); $thread->join; threads->detach; $thread->detach; my $tid = $thread->tid; my $owntid = threads->tid; my $self = threads->self; my $threadx = threads->object( $tidx ); threads->yield(); $_->join foreach threads->list; unless (fork) { threads->isthread; # intended to be used in a child-init Apache handler } use forks qw(debug); threads->debug( 1 ); perl -Mforks -Mforks::shared threadapplication
The "forks" pragma allows a developer to use threads without having to have a threaded perl, or to even run 5.8.0 or higher. There were a number of goals that I am trying to reach with this implementation.
The standard Perl 5.8.0 threads implementation is very memory consuming, which makes it basically impossible to use in a production environment, particularly with mod_perl and Apache. Because of the use of the standard Unix fork() capabilities, most operating systems will be able to use the Copy-On-Write (COW) memory sharing capabilities (whereas with the standard Perl 5.8.0 threads implementation, this is thwarted by the Perl interpreter cloning process that is used to create threads). The memory savings have been confirmed.
This threads implementation allows you to use a standard, pre-forking Apache server and have the children act as threads (with the class method isthread). This is as yet untested within Apache, but should work.
You should be able to run threaded applications unchanged by simply making sure that the "forks.pm" and "forks::shared.pm" modules are loaded, e.g. by specifying them on the command line. This still doesn't work for all source code because the : shared attribute has not yet been implemented. Patches for this are welcomed.
: shared
Because you do not need a threaded Perl to use forks.pm, you can start prototyping threaded applications with the Perl executable that you are used to. Just download the "forks.pm" package from CPAN and install that. So the threshold for trying out threads in Perl has become much lower. Even Perl 5.005 should in principle be able to support the forks.pm module: because of some issues with regards to the availability of XS features between different versions of Perl, it seems that 5.6.0 (unthreaded) is what you need at least.
There are still a lot of things to do, but the basic functionalities seem to work. The missing pieces are just a matter of programming. If you would like to participate in this, please do! Patches are welcome!
This version is mostly written in Perl. Inter-process communication is done by using sockets, with the process that stores the shared variables as the server and all the processes that function as threads, as clients.
The reason I chose sockets for inter-thread communication above using a shared memory library, is that a blocking socket allows you to elegantly solve the problem of a thread that is blocking for a certain event. Any polling that might occur, is not occurring at the Perl level, but at the level of the socket, which should be much better and probably very optimized already.
Apart from the standard class methods, the following class methods are supplied by the "forks" threads implementation.
unless (fork) { threads->isthread; # this process is a detached thread now exit; # can not return values, as thread is detached }
The "isthread" class method attempt to make a connection with the shared variables process. If it succeeds, then the process will function as a detached thread and will allow all the threads methods to operate.
This method is mainly intended to be used from within a child-init handler in a pre-forking Apache server. All the children that handle requests become threads as far as Perl is concerned, allowing you to use shared variables between all of the Apache processes.
threads->debug( 1 ); $debug = threads->debug;
The "debug" class method allows you to (re)set a flag which causes extensive debugging output of the communication between threads to be output to STDERR. The format is still subject to change and therefore still undocumented.
Some caveats that you need to be aware of.
Because of the use of sockets for inter-thread communication, there is an inherent larger latency with the interaction between threads. However, the fact that sockets are used, may open up the possibility to share threads over more than one physical machine.
To get forks.pm working on Perl 5.6.x, it was necessary to use a source filter to ensure a smooth upgrade path from using forks under Perl 5.6.x to Perl 5.8.x and higher. The source filter used is pretty simple and may prove to be too simple. Please report any problems that you may find when running under 5.6.x.
These problems are known and will be fixed in the future:
Although there are no errors in the test-suite, the test harness sometimes thinks there is something wrong because of an unexpected exit() value. Not sure what to do about this yet.
Juerd Waalboer for pointing me to the source filter solution for Perl 5.6.x.
Bradley W. Langhorst for making sure everything runs with warnings enabled.
Lars Fenneberg for helping me through the initial birthing pains.
Arthur Bergman for implementing the first working version of Perl threads support and providing us with an API to build on.
And all the other people reporting problems.
Elizabeth Mattijsen, <liz@dijkmat.nl>.
Please report bugs to <perlbugs@dijkmat.nl>.
Copyright (c) 2002-2003 Elizabeth Mattijsen <liz@dijkmat.nl>. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
threads.
To install forks, copy and paste the appropriate command in to your terminal.
cpanm
cpanm forks
CPAN shell
perl -MCPAN -e shell install forks
For more information on module installation, please visit the detailed CPAN module installation guide.