forks::shared(3pm)

πŸ’– forks::shared πŸ’– β€” the Perl manual page, but make it a group chat 🫢

okay bestie, welcome to forks::shared(3pm) β€” a drop-in replacement for Perl threads::shared with forks(). yes, that's the whole name, and yes it slays. this is the User Contributed Perl Documentation page for it, and i'm about to walk you through it like we're texting at 2am. let's go πŸ’…


✨ SYNOPSIS ✨

so here's the vibe. this is literally the code you type:

use forks;
use forks::shared;

my $variable : shared;
my @array    : shared;
my %hash     : shared;

share( $variable );
share( @array );
share( %hash );

$variable = shared_clone($non_shared_ref_value);
$variable = shared_clone({'foo' => [qw/foo bar baz/]});

lock( $variable );
cond_wait( $variable );
cond_wait( $variable, $lock_variable );
cond_timedwait( $variable, abs time );
cond_timedwait( $variable, abs time, $lock_variable );
cond_signal( $variable );
cond_broadcast( $variable );

bless( $variable, class name );

# Enable deadlock detection and resolution
use forks::shared deadlock => {
  detect => 1,
  resolve => 1
};
# or
threads::shared->set_deadlock_option(
  detect  => 1,
  resolve  => 1
);

look at that. iconic. no notes πŸ’…


🌸 DESCRIPTION 🌸

the forks::shared pragma lets you use shared variables with threads (threads implemented via the forks pragma, iykyk) without having to have a threaded perl. like, you don't even need to be running 5.8.0 or higher. fr fr.

and here's the tea: forks::shared is currently API compatible with CPAN threads::shared version 1.05. periodt. πŸŽ€


🎁 EXPORT 🎁

it exports these babies:

share, shared_clone, cond_wait, cond_timedwait, cond_signal, cond_broadcast, is_shared, bless

if you want the details, go read "EXPORT" in threads::shared β€” that's where the full lore lives. πŸ“š


πŸ¦‹ OBJECTS πŸ¦‹

bestie, forks::shared exports its own version of bless() that actually works on shared objects β€” so blessings propagate across threads. the way that works is genuinely so satisfying 😭✨

usage info? see threads::shared. extra examples? the forks test suite has you covered.


πŸ”₯ EXTRA FEATURES πŸ”₯

πŸ‘‘ Deadlock detection and resolution πŸ‘‘

in the interest of helping programmers debug one of the most common bugs in threaded application software, forks::shared supports a full deadlock detection and resolution engine. yes, a whole engine. it's giving main character energy.

🌟 Automated detection and resolution 🌟

two ways to turn these features on, bestie:

way one β€” at import time, in a use statement, like:

use forks::shared deadlock => { OPTIONS }

way two β€” during runtime, as a class method call to set_deadlock_option, like:

forks::shared->set_deadlock_option( OPTIONS );
#or
threads::shared->set_deadlock_option( OPTIONS );

and OPTIONS can be any combination of these:

  • detect β€” 1 (enable) or 0 (disable)
  • period β€” number of seconds between asynchronous polls
  • resolve β€” 1 (enable) or 0 (disable)

the detect option enables deadlock detection. by itself, this option enables synchronous deadlock detection, which efficiently checks for potential deadlocks at lock() time. and if any are detected and warnings are enabled, it prints out details to STDERR like this example:

Deadlock detected:
    TID   SV LOCKED   SV LOCKING   Caller
      1           3            4   t/forks06.t at line 41
      2           4            3   t/forks06.t at line 46

the period option, if you set it to a value greater than zero, is the number of seconds between asynchronous deadlock detection checks. asynchronous detection is useful for debugging those rare, time-critical race conditions leading to deadlocks that might get masked by the slight time overhead that synchronous detection adds on every single lock() call. also, overall, it's less CPU intensive than synchronous deadlock detection. slay. 🌈

the resolve option enables auto-termination of one thread in each deadlocked thread pair that has been detected. just like with detect, resolve prints out the action it performs to STDERR, if warnings are enabled.

⚠️ NOTE, and i need you to actually read this one bestie: resolve uses SIGKILL to break deadlocks. so do not use this feature in environments where the stability of the rest of your application might be adversely affected by process death in this manner. like. it's killing processes. πŸ’€

for example:

use forks;
use forks::shared
    deadlock => {detect=> 1, resolve => 1};

🧚 Manual detection 🧚

if you'd rather check for deadlocks yourself without enabling automated deadlock detection, forks provides an additional thread object method:

$thr->is_deadlocked()

which reports whether the thread in question is currently deadlocked. you can use this method in conjunction with the resolve deadlock option to auto-terminate offending threads. teamwork! 🫢

πŸ“ Splice on shared array πŸ“

as of at least threads::shared 1.05, the splice function has not been implemented for arrays. however β€” and this is the glow-up β€” forks::shared fully supports splice on shared arrays. ate that. πŸ’…

πŸ’œ share() doesn't lose value for arrays and hashes πŸ’œ

in the standard Perl threads implementation, arrays and hashes get re-initialized when they become shared via the share() function. the share() function of forks::shared does not initialize arrays and hashes when they become shared with the share() function.

this could be considered a bug in the standard Perl implementation. in any case, it's an inconsistency between the behaviour of threads.pm and forks.pm. πŸ™ˆ

now, if you do not have a natively threaded perl, and you've installed and are using forks in "threads.pm" override mode (which is where use threads loads forks.pm), then this module will explicitly emulate the behavior of standard threads::shared and lose value for arrays and hashes with share(). additionally, the array splice function will become a no-op with a warning. 😭

you can also enable this mode by setting the environment variable THREADS_NATIVE_EMULATION to a true value before you run your script. see "Native threads 'to-the-letter' emulation mode" in forks for more info. πŸ“


😬 CAVIATS 😬

(okay yes, the original heading is spelled CAVIATS β€” i'm not touching it, it's part of the charm now πŸŽ€)

some caveats you need to be aware of.

πŸ’€ Storing CODE refs in shared variables πŸ’€

since forks::shared requires Storable to serialize shared data structures, storing CODE refs in shared variables is not enabled by default (primarily for security reasons, and honestly? fair).

if you need to share CODE refs between threads, the minimum you must do before storing CODE refs is:

$Storable::Deparse = $Storable::Eval = 1;

see "CODE_REFERENCES" in Storable for detailed information β€” including the potential security risks and ways to protect yourself against them. please actually read that part. 🫢

🌸 test-suite exits in a weird way 🌸

although there are no errors in the test-suite, the test harness sometimes thinks something is 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 gets patched in the future, but for now β€” the warnings are harmless and may be safely ignored. it's not you, it's the END block. πŸ’…


πŸ‘‘ CURRENT AUTHOR AND MAINTAINER πŸ‘‘

Eric Rybski <rybskej@yahoo.com>. please send all module inquries to me.


πŸŽ€ ORIGINAL AUTHOR πŸŽ€

Elizabeth Mattijsen, <liz@dijkmat.nl>.


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::shared, forks, forks::BerkeleyDB::shared.


okay that's the whole page bestie, you made it πŸ₯³ no cap, that was a lot of words but you ate every single one. this one's from perl v5.42.3, dated 2026-08-20, and it lives at forks::shared(3pm) β€” go forth and share your variables responsibly πŸ’–βœ¨πŸ¦‹

πŸ“¦ where this page comes from