Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
forks(3)	      User Contributed Perl Documentation	      forks(3)

NAME
       forks - drop-in replacement for Perl threads using fork()

VERSION
       This documentation describes version 0.36.

SYNOPSIS
	 use forks;    #ALWAYS LOAD AS FIRST MODULE, if	possible
	 use warnings;

	 my $thread = threads->new( sub	{	# or ->create or async()
	   print "Hello	world from a thread\n";
	 } );

	 $thread->join;

	 $thread = threads->new( { 'context' =>	'list' }, sub {
	   print "Thread is expected to	return a list\n";
	   return (1, 'abc', 5);
	 }
	 my @result = $thread->join();

	 threads->detach;
	 $thread->detach;

	 my $tid    = $thread->tid;
	 my $owntid = threads->tid;

	 my $self    = threads->self;
	 my $threadx = threads->object(	$tidx );

	 my @running = threads->list(threads::running);
	 $_->join() foreach (threads->list(threads::joinable));
	 $_->join foreach threads->list; #block	until all threads done

	 unless	(fork) {
	   threads->isthread; #	could be used a	child-init Apache handler
	 }

	 # Enable debugging
	 use forks qw(debug);
	 threads->debug( 1 );

	 # Stringify thread objects
	 use forks qw(stringify);

	 # Check state of a thread
	 my $thr = threads->new( ... );
	 if ($thr->is_running()) {
	   print "Thread $thr running\n"; #prints "Thread 1 running"
	 }

	 # Send	a signal to a thread
	 $thr->kill('SIGUSR1');

	 # Manual deadlock detection
	 if ($thr->is_deadlocked()) {
	   print "Thread $thr is currently deadlocked!\n";
	 }

	 # Use forks as	a drop-in replacement for an ithreads application
	 perl -Mforks threadapplication

       See "SYNOPSIS" in threads for more examples.

DESCRIPTION
       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.

       Refer to	the threads module for ithreads	API documentation.  Also, use

	   perl	-Mforks	-e 'print $threads::VERSION'

       to see what version of threads you should refer to regarding supported
       API features.

       There were a number of goals that I am trying to	reach with this
       implementation.

	 Using this module only	makes sense if you run on a system that	has an
	 implementation	of the "fork" function by the Operating	System.
	 Windows is currently the only known system on which Perl runs which
	 does not have an implementation of "fork".  Therefore,	it doesn't
	 make any sense	to use this module on a	Windows	system.	 And
	 therefore, a check is made during installation	barring	you from
	 installing on a Windows system.

   module load order: forks first
       Since forks overrides core Perl functions, you are *strongly*
       encouraged to load the forks module before any other Perl modules.
       This will insure	the most consistent and	stable system behavior.	 This
       can be easily done without affecting existing code, like:

	   perl	-Mforks	 script.pl

   memory usage
       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.

   mod_perl / Apache
       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").

   same	API as threads
       You should be able to run threaded applications unchanged by simply
       making sure that	the "forks" and	"forks::shared"	modules	are loaded,
       e.g. by specifying them on the command line.  Forks is currently	API
       compatible with CPAN threads version 1.53.

       Additionally, you do not	need to	worry about upgrading to the latest
       Perl maintenance	release	to insure that the (CPAN) release of threads
       you wish	to use is fully	compatibly and stable.	Forks code is
       completely independent of the perl core,	and thus will guarantee
       reliable	behavior on any	release	of Perl	5.8 or later.  (Note that
       there may be behavior variances if running under	Perl 5.6.x, as that
       version does not	support	safe signals and requires a source filter to
       load forks).

   using as a development tool
       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 and install the "forks" package from CPAN.  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; however,	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.

       Additionally, forks offers a full thread	deadlock detection engine, to
       help discover and optionally resolve locking issues in threaded
       applications.  See "Deadlock detection and resolution" in forks::shared
       for more	information.

   using in production environments
       This package has	successfully been proven as stable and reliable	in
       production environments.	 I have	personally used	it in high-
       availability, database-driven, message processing server	applications
       since 2004 with great success.

       Also, unlike pure ithreads, forks.pm is fully compatible	with all perl
       modules,	whether	or not they have been updated to be ithread safe.
       This means that you do not need to feel limited in what you can develop
       as a threaded perl application, a problem that continues	to plague the
       acceptance of ithreads in production enviroments	today.	Just handle
       these modules as	you would when using a standard	fork: be sure to
       create new instances of,	or connections to, resources where a single
       instance	can not	be shared between multiple processes.

       The only	major concern is the potentially slow (relative	to pure
       ithreads) performance of	shared data and	locks.	If your	application
       doesn't depend on extensive semaphore use, and reads/writes from	shared
       variables moderately (such as using them	primarily to deliver data to a
       child thread to process and the child thread uses a shared structure to
       return the result), then	this will likely not be	an issue for your
       application.  See the TODO section regarding plans to tackle this
       issue.

       Also, you may wish to try forks::BerkeleyDB, which has shown
       signifigant performance gains and consistent throughoutput in high-
       concurrency shared variable applications.

   Perl	built without native ithreads
       If your Perl release was	not built with ithreads	or does	not support
       ithreads, you will have a compile-time option of	installing forks into
       the threads and threads::shared namespaces.  This is done as a
       convenience to give users a reasonably seamless ithreads	API experience
       without having to rebuild their distribution with native	threading (and
       its slight performance overhead on all perl runtime, even if not	using
       threads).

       Note: When using	forks in this manner (e.g. "use	threads;") for the
       first time in your code,	forks will attempt to behave identically to
       threads relative	to the current version of threads it supports (refer
       to $threads::VERSION), even if the behavior is (or was) considered a
       bug.  At	this time, this	means that shared variables will lose their
       pre-existing value at the time they are shared and that splice will die
       if attempted on a shared	scalar.

       If you use forks	for the	first time as "use forks" and other loaded
       code uses "use threads",	then this threads behavior emulation does not
       apply.

REQUIRED MODULES
	Acme::Damn (any)
	Attribute::Handlers (any)
	Devel::Symdump (any)
	File::Spec (any)
	if (any)
	IO::Socket (1.18)
	List::MoreUtils	(0.15)
	Scalar::Util (1.11)
	Storable (any)
	Sys::SigAction (0.11)
	Test::More (any)
	Time::HiRes (any)

IMPLEMENTATION
       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.

   why sockets?
       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.

EXTRA CLASS METHODS
       Apart from the standard class methods, the following class methods are
       supplied	by the "forks" threads implementation.

   isthread
	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.  See
       Apache::forks for more information.

   debug
	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.

       Debugging can only be switched on by defining the environment variable
       "THREADS_DEBUG".	 If the	environment variable does not exist when the
       forks.pm	module is compiled, then all debugging code will be optimised
       away to create a	better performance.  If	the environment	variable has a
       true value, then	debugging will also be enabled from the	start.

EXTRA FEATURES
   Native threads 'to-the-letter' emulation mode
       By default, forks behaves slightly differently than native ithreads,
       regarding shared	variables.  Specifically, native threads does not
       support splice()	on shared arrays, nor does it retain any pre-existing
       values of arrays	or hashes when they are	shared;	however, forks
       supports	all of these functions.	 These are behaviors are considered
       limitations/bugs	in the current native ithread implementation.

       To allow	for complete drop-in compatibility with	scripts	and modules
       written for threads.pm, you may specify the environment variable
       "THREADS_NATIVE_EMULATION" to a true value before running your script.
       This will instruct forks	to behave exactly as native ithreads would in
       the above noted situations.

       This mode may also be enabled by	default	(without requiring this
       environment variable if you do not have a threaded Perl and wish	to
       install forks as	a full drop-in replacement.  See "Perl built without
       native ithreads"	for more information.

   Deadlock detection
       Forks also offers a full	thread deadlock	detection engine, to help
       discover	and optionally resolve locking issues in threaded
       applications.  See "Deadlock detection and resolution" in forks::shared
       for more	information.

   Perl	debugger support
       Forks supports basic compabitility with the Perl	debugger.  By default,
       only the	main thread to the active terminal (TTY), allowing for
       debugging of scripts where child	threads	are run	as background tasks
       without any extra steps.

       If you wish to debug code executed in child threads, you	may need to
       perform a few steps to prepare your environment for multi-threaded
       debugging.

       The simplest option is run your script in xterm,	as Perl	will
       automatically create additional xterm windows for each child thread
       that encounters a debugger breakpoint.

       Otherwise, you will need	to manually tell Perl how to map a control of
       thread to a TTY.	 Two undocumented features exist in the	Perl debugger:

       1. Define global	variable $DB::fork_TTY as the first stem in the
       subroutine for a	thread.	 The value must	be a valid TTY name, such as
       '/dev/pts/1' or '/dev/ttys001'; valid names may vary across platforms.
       For example:

	   threads->new(sub {
	       $DB::fork_TTY = '/dev/tty003'; #tie thread to TTY 3
	       ...
	   });

       Also, the TTY must be active and	idle prior to the thread executing.
       This normally is	accomplished by	opening	a new local or remote session
       to your machine,	identifying the	TTY via	`tty`, and then	typing `sleep
       10000000` to prevent user input from being passed to the	command	line
       while you are debugging.

       When the	debugger halts at a breakpoint in your code in a child thread,
       all output and user input will be managed via this TTY.

       2. Define subroutine DB::get_fork_TTY()

       This subroutine will execute once each child thread as soon as it has
       spawned.	 Thus, you can create a	new TTY, or simply bind	to an existng,
       active TTY.  In this subroutine,	you should define a unique, valid TTY
       name for	the global variable $DB::fork_TTY.

       For example, to dynamically spawn a new xterm session and bind a	new
       thread to it, you could do the following:

       sub DB::get_fork_TTY {
	   open	XT, q[3>&1 xterm -title	'Forked	Perl debugger' -e sh -c
       'tty1>&3;\ sleep	10000000' |];
	   $DB::fork_TTY = <XT>;
	   chomp $DB::fork_TTY;	}

       For more	information and	tips, refer to this excellent Perl Monks
       thread: "/www.perlmonks.org/?node_id=128283"" in	<a
       href="http:Debugging Several Proccesses at Same Time</a>>.

   INET	socket IP mask
       For security, inter-thread communication	INET sockets only will allow
       connections from	the default local machine IPv4 loopback	address	(e.g
       127.0.0.1).  However, this filter may be	modified by defining the
       environment variable "THREADS_IP_MASK" with a standard perl regular
       expression (or with no value, which would disable the filter).

   UNIX	socket support
       For users who do	not wish to (or	can not) use TCP sockets, UNIX socket
       support is available.  This can be only switched	on by defining the
       environment variable "THREADS_SOCKET_UNIX".  If the environment
       variable	has a true value, then UNIX sockets will be used instead of
       the default TCP sockets.	 Socket	descriptors are	currently written to
       /var/tmp	and given a+rw access by default (for cleanest functional
       support on multi-user systems).

       This feature is excellent for applications that require extra security,
       as it does not expose forks.pm to any INET vunerabilities your system
       may be subject to (i.e. systems not protected by	a firewall).  It also
       may provide an additional performance boost, as there is	less system
       overhead	necessary to handle UNIX vs INET socket	communication.

   Co-existance	with fork-aware	modules	and environments
       For modules that	actively monitor and clean up after defunct child
       processes like POE, forks has added support to switch the methodology
       used to maintain	thraad group state.  This feature is switched on by
       defining	the environment	variable "THREADS_DAEMON_MODEL".  An example
       use might be:

	   THREADS_DAEMON_MODEL=1 perl -Mforks -MPOE threadapplication

       This function essentially reverses the parent-child relationship
       between the main	thread and the thread state process that forks.pm
       uses.  Extra care has gone into retaining full system signal support
       and compatibility when using this mode, so it should be quite stable.

NOTES
       Some important items you	should be aware	of.

   Signal behavior
       Unlike ithreads,	signals	being sent are standard	OS signals, so you
       should program defensively if you plan to use inter-thread signals.

       Also, be	aware that certain signals may untrappable depending on	the
       target platform,	such as	SIGKILL	and SIGSTOP.  Thus, it is recommended
       you only	use normal signals (such as TERM, INT, HUP, USR1, USR2)	for
       inter-thread signal handling.

   exit() behavior
       If you call exit() in a thread other than the main thread and exit
       behavior	is configured to cause entire application to exit (default
       behavior), be aware that	all other threads will be agressively
       terminated using	SIGKILL.  This will cause END blocks and global
       destruction to be ignored in those threads.

       This behavior conforms to the expected behavior of native Perl threads.
       The only	subtle difference is that the main thread will be signaled
       using SIGABRT to	immediately exit.

       If you call "fork()" but	do not call <threads->isthread()>, then	the
       child process will default to the pre-existing CORE::GLOBAL::exit() or
       CORE::exit() behavior.  Note that such processes	are exempt from
       application global termination if exit()	is called in a thread, so you
       must manually clean up child processes created in this manner before
       exiting your threaded application.

   END block behavior
       In native ithreads, END blocks are only executed	in the thread in which
       the code	was loaded/evaluated.  However,	in forks, END blocks are
       processed in all	threads	that are aware of such code segments (i.e.
       threads started after modules with END blocks are loaded).  This	may be
       considered a bug	or a feature depending on what your END	blocks are
       doing, such as closing important	external resources for which each
       thread may have it's own	handle.

       In general, it is a good	defensive programming practice to add the
       following to your END blocks when you want to insure sure they only are
       evaluated in the	thread that they were created in:

	   {
	       my $tid = threads->tid if exists	$INC{'threads.pm'};
	       END {
		   return if defined($tid) && $tid != threads->tid;
		   # standard end block	code goes here
	       }
	   }

       This code is completely compatible with native ithreads.	 Note that
       this behavior may change	in the future (at least	with
       THREADS_NATIVE_EMULATION	mode).

   Modifying signals
       Since the threads API provides a	method to send signals between threads
       (processes), untrapped normal and error signals are defined by forks
       with a basic exit() shutdown function to	provide	safe termination.

       Thus, if	you (or	any modules you	use) modify signal handlers, it	is
       important that the signal handlers at least remain defined and are not
       undefined (for whatever reason).	 The system signal handler default,
       usually abnormal	process	termination which skips	END blocks, may	cause
       undesired behavior if a thread exits due	to an unhandled	signal.

       In general, the following signals are considered	"safe" to trap and use
       in threads (depending on	your system behavior when such signals are
       trapped):

	   HUP INT PIPE	TERM USR1 USR2 ABRT EMT	QUIT TRAP

   Modules that	modify %SIG or use POSIX::sigaction()
       To insure highest stability, forks ties some hooks into the global %SIG
       hash to co-exist	as peacefully as possible with user-defined signals.
       This has	a few subtle, but important implications:

	   - As	long as	you modify signals using %SIG, you should never	encounter any
	   unexpected issues.

	   - If	you use	POSIX::sigaction, it may subvert protections that forks	has
	   added to the	signal handling	system.	 In normal circumstances, this will not
	   create any run-time issues; however,	if you also attempt to access shared
	   variables in	signal handlers	or END blocks, you may encounter unexpected
	   results.  Note: if you do use sigaction, please avoid overloading the ABRT
	   signal in the main thread, as it is used for	process	group flow control.

   Modules that	modify $SIG{CHLD}
       In order	to be compatible with perl's core system() function on all
       platforms, extra	care has gone into implementing	a smarter $SIG{CHLD}
       in forks.pm.  The only functional effect	is that	you will never need to
       (or be able to) reap threads (processes)	if you define your own CHLD
       handler.

       You may define the environment variable THREADS_SIGCHLD_IGNORE to to
       force forks to use 'IGNORE' on systems where a custom CHLD signal
       handler has been	automatically installed	to support correct exit	code
       of perl core system() function.	Note that this should *not* be
       necessary unless	you encounter specific issues with the forks.pm	CHLD
       signal handler.

   $thr->wantarray() returns void after	$thr->join or $thr->detach
       Be aware	that thread return context is purged and $thr->wantarray will
       return void context after a thread is detached or joined.  This is done
       to minimize memory in programs that spawn many (millions	of) threads.
       This differs from default threads.pm behavior, but should be acceptable
       as the context no longer	serves a functional purpose after a join or
       detach.	Thus, if you still require thread context information after a
       join, be	sure to	request	and store the value of $thr->wantarray first.

   $thr->get_stack_size() returns default after	$thr->join or $thr->detach
       Thread stack size information is	purged and $thr->get_stack_size	will
       return the current threads default after	a thread is detached or
       joined.	This is	done to	minimize memory	in programs that spawn many
       (millions of) threads.  This differs from default threads.pm behavior,
       which retains per-thread	stack size information indefinitely.  Thus, if
       you require individual thread stack size	information after a join or
       detach, be sure to request and store the	value of $thr->get_stack_size
       first.

   Modules that	modify CORE::GLOBAL::fork()
       This modules goes to great lengths to insure that normal	fork behavior
       is seamlessly integrated	into the threaded environment by overloading
       CORE::GLOBAL::fork.  Thus, please refrain from overloading this
       function	unless absolutely necessary.  In such a	case, forks.pm
       provides	a set of four functions:

	   _fork_pre
	   _fork
	   _fork_post_parent
	   _fork_post_child

       that represent all possible functional states before and	after a	fork
       occurs.	These states must be called to insure that fork() works	for
       both threads and	normal fork calls.

       Refer to	forks.pm source	code, *CORE::GLOBAL::fork = sub	{ ... }
       definition as an	example	usage.	Please contact the author if you have
       any questions regarding this.

CAVEATS
       Some caveats that you need to be	aware of.

   Greater latency
       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 TCP sockets are used, may	open up	the
       possibility to share threads over more than one physical	machine.

       You may decrease	some latency by	using UNIX sockets (see	"UNIX socket
       support").

       Also, you may wish to try forks::BerkeleyDB, which has shown
       signifigant performance gains and consistent throughoutput in
       applications requiring high-concurrency shared variable access.

   Module CLONE	& CLONE_SKIP functions and threads
       In rare cases, module CLONE functions may have issues when being	auto-
       executed	by a new thread	(forked	process).  This	only affects modules
       that use	XS data	(objects or struts) created by to external C
       libraries.  If a	module attempts	to CLONE non-fork safe XS data,	at
       worst it	may core dump only the newly created thread (process).

       If CLONE_SKIP function is defined in a package and it returns a true
       value, all objects of this class	type will be undefined in new threads.
       This is generally the same behavior as native threads with Perl 5.8.7
       and later.  See <<a
       href="http://perldoc.perl.org/perlmod.html#Making-your-module-threadsafe-threadsafe-thread-safe-module%2c-threadsafe-module%2c-thread-safe-CLONE-CLONE_SKIP-thread-threads-ithread">perlmod</a>>
       for more	information.

       However,	two subtle behavior variances exist relative to	native Perl
       threads:

	   1. The actual undefining of variables occurs	in the child thread.  This should
	   be portable with all	non-perl modules, as long as those module datastructures can be
	   safely garbage collected in the child thread	(note that DESTROY will	not be called).

	   2. Arrays and hashes	will be	emptied	and unblessed, but value will not be converted
	   to an undef scalar ref.  This differs from native threads, where all	references
	   become an undef scalar ref.	This should be generally harmless, as long as you are
	   careful with	variable state checks (e.g. check whether reference is still blessed,
	   not whether the reftype has changed,	to determine if	it is still a valid object
	   in a	new thread).

       Overall,	if you treat potentially sensitive resources (such as DBI
       driver instances) as non-thread-safe by default and close these
       resources prior to creating a new thread, you should never encounter
       any portability issues.

   Can't return	unshared filehandles from threads
       Currently, it is	not possible to	return a file handle from a thread to
       the thread that is joining it.  Attempting to do	so will	throw a
       terminal	error.	However, if you	share the filehandle first with
       forks::shared, you can safely return the	shared filehandle.

   Signals and safe-signal enabled Perl
       In order	to use signals,	you must be using perl 5.8 compiled with safe
       signal support.	Otherwise, you'll get a	terminal error like "Cannot
       signal threads without safe signals" if you try to use signal
       functions.

   Source filter
       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.

TODO
       See the TODO file in the	distribution.

KNOWN PROBLEMS
       These problems are known	and will hopefully be fixed in the future:

       test-suite exits	in a weird way
	 Although there	are no errors in the test-suite, the test harness
	 sometimes thinks there	is something wrong because of an unexpected
	 exit()	value.	This is	an issue with Test::More's END block, which
	 wasn't	designed to co-exist with a threads environment	and forked
	 processes.  Hopefully,	that module will be patched in the future, but
	 for now, the warnings are harmless and	may be safely ignored.

	 And of	course,	there might be other, undiscovered issues.  Patches
	 are welcome!

CREDITS
       Refer to	the "CREDITS" file included in the distribution.

CURRENT	AUTHOR AND MAINTAINER
       Eric Rybski <rybskej@yahoo.com>.	 Please	send all module	inquries to
       me.

ORIGINAL AUTHOR
       Elizabeth Mattijsen, <liz@dijkmat.nl>.

COPYRIGHT
       Copyright (c)
	2005-2014 Eric Rybski <rybskej@yahoo.com>,
	2002-2004 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.

SEE ALSO
       threads,	forks::BerkeleyDB, Apache::forks.

perl v5.32.0			  2020-08-09			      forks(3)

NAME | VERSION | SYNOPSIS | DESCRIPTION | REQUIRED MODULES | IMPLEMENTATION | EXTRA CLASS METHODS | EXTRA FEATURES | NOTES | CAVEATS | TODO | KNOWN PROBLEMS | CREDITS | CURRENT AUTHOR AND MAINTAINER | ORIGINAL AUTHOR | COPYRIGHT | SEE ALSO

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=forks&sektion=3&manpath=FreeBSD+12.2-RELEASE+and+Ports>

home | help