The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

forks::BerkeleyDB - high-performance drop-in replacement for threads

VERSION

This documentation describes version 0.052.

SYNOPSYS

  use forks::BerkeleyDB;

  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::BerkeleyDB -Mforks::BerkeleyDB::shared threadapplication

DESCRIPTION

forks::BerkeleyDB is a drop-in replacement for threads, written as an extension of forks. The goal of this module is to improve upon the core performance of forks at a level comparable to native ithreads.

REQUIRED MODULES

 BerkeleyDB (0.27)
 Devel::Required (0.07)
 forks (0.23)
 Storable (any)
 Tie::Restore (0.11)

USAGE

See forks for common usage information.

NOTES

If you have forks.pm 0.23 or later installed, all database files created during runtime will be automatically purged when the main thread exits. If you have created a large number of shared variables, you may experience a slight delay during process exit. Note that these files may not be cleaned up if the main thread or process group is terminated using SIGKILL, although existance of these files after exit should not have an adverse affect on other currently running or future forks::BerkeleyDB processes.

Testing has been performed against BerkeleyDB 4.3.x. Full compatibility is expected with BDB 4.x and likely with 3.x as well. Unclear if all tie methods are compatible with 2.x. This module is currently not compatible with BDB 1.x.

CAVIATS

This module defines CORE::GLOBAL::fork to insure BerkeleyDB resources are correctly managed before and after a fork occurs. This insures that processes will be able to safely use threads->isthread. You may encounter issues with your application or other modules it uses also define CORE::GLOBAL::fork. To work around this, you should modify your CORE::GLOBAL::fork to support chaining, like the following

        use subs 'fork';
        *_oldfork = \&CORE::GLOBAL::fork;
        sub fork {
                #your code here
                ...
                _oldfork->() if ref(*oldfork) eq 'SUB';
        }

TODO

Implement thread joined data using BerkeleyDB.

Determine what additional functions should be migrated to BerkeleyDB backend vs. those that should remain as part of the forks package.

Add a high security mode, where all BerkeleyDB data is encrypted using either native encryption (preferred, if available) or an external cryptography module of the user's choice (i.e. Crypt::* interface module, or something that supports a standard interface given an object instance).

Consider porting all shared variable tied class support into package classes, instead of depending on BerkeleyDB module parent classes for some methods, to insure method behavior consistency no matter which BerkeleyDB.pm version is installed.

Consider merging shared scalars into one or more BDB recno tables, to minimize use of environment locks and database files (at the cost of write cursor performance, if multiple threads attempting to write to different SVs in same physical table).

Consider rewriting all SV actions to use write cursor (unless complete action is already atomic in BDB API) to insure perltie actions are atomic in nature. Intention is to allow use of SV without always requiring a lock (for apps that require highest possible concurrency).

Consider implementing "atomic" shared variable classes, which allow all non-iterative operations to be atomic without locks. This would require overload of all math and string operators. Hopefully this will be enabled with an attribute, such as 'sharedatomic'. I don't believe this can be achieved with perltie, so only non-blessed primitives would be allowed for scalars.

May need to enable DB_ENV->failchk when shared var process detects that a thread has unexpectedly exited. If return value is DB_RUNRECOVERY, then we likely need to terminate the entire application (as the shared bdb environment is no longer guaranteed to be stable.

Consider using bdb txn subsystem environment for locking and signaling. Theoretically, this should require: 1 recno for locks (idx=sid, value=tid holding lock), 1 recno for waiting (idx=sid, value=[list if tid waiting]), and N queue for signaling (1 per thread; thread block on own queue to wimulate waiting; push from other source acts as signal). Txn would be used on locks and waiting recno databases (locking individual elements with cursors). Deadlock detection could be enabled using BDB deadlock detection engine. Would need hooks into deadlock detection forks.pm interface.

CAVIATS

It appears that BerkeleyDB libdb 4.4.x environments are not fully thread-safe with BerkeleyDB CDB mode on some platforms. Thus, it is highly recommended you use libdb 4.3.x and earlier, or 4.5.x and later.

AUTHOR

Eric Rybski <rybskej@yahoo.com>.

COPYRIGHT

Copyright (c) 2006-2007 Eric Rybski <rybskej@yahoo.com>. 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

forks, threads