http://qs321.pair.com?node_id=1216583


in reply to Re^7: Why should any one use/learn Perl 6?
in thread Why should any one use/learn Perl 6?

Greetings liz,

A mutex is necessary whenever the Perl-like behavior, via the TIE interface, involves 2 IPC calls { FETCH and STORE }.

use strict; use warnings; use feature 'say'; use MCE::Hobo; use MCE::Mutex; use MCE::Shared; my $mutex = MCE::Mutex->new(); tie my $var, 'MCE::Shared', 0; sub task { for ( 1 .. 2000 ) { $mutex->enter(sub { $var += 1; # FETCH, STORE $var += 4; # Ditto }); } } MCE::Hobo->create(\&task) for 1 .. 4; MCE::Hobo->waitall; say $var; # 40000

A mutex is not necessary via the OO interface. MCE::Shared::{ Array, Hash, and Scalar } include sugar methods.

use strict; use warnings; use feature 'say'; use MCE::Hobo; use MCE::Shared; my $var = MCE::Shared->scalar(0); sub task { for ( 1 .. 2000 ) { $var->incr; $var->incrby(4); } } MCE::Hobo->create(\&task) for 1 .. 4; MCE::Hobo->waitall; say $var->get; # 40000

MCE::Shared works with threads and other parallel modules. Below, the same thing using threads.

use strict; use warnings; use feature 'say'; use threads; use MCE::Shared; my $var = MCE::Shared->scalar(0); sub task { for ( 1 .. 2000 ) { $var->incr; $var->incrby(4); } } threads->create(\&task) for 1 .. 4; $_->join for threads->list; say $var->get; # 40000

One may also customize the shared class feasibly.

use strict; use warnings; package My::Scalar; use MCE::Shared::Scalar; use base 'MCE::Shared::Scalar'; sub set_if_max { # my ( $self, $value ) = @_; ${ $_[0] } = $_[1] if ( $_[1] > ${ $_[0] } ); 1; } 1; package main; use feature 'say'; use MCE::Shared; my $var = MCE::Shared->share( { module => 'My::Scalar' }, 0 ); $var->set_if_max(42); $var->set_if_max(11); say $var->get; # 42

Regards, Mario

Replies are listed 'Best First'.
Re^9: Why should any one use/learn Perl 6?
by liz (Monsignor) on Jun 13, 2018 at 22:26 UTC

    Thank you for your elaboration.

    If I understand you correctly, you either have a little boilerplate with tie

    tie my $var, 'MCE::Shared', 0; $var = 42;

    or you have a lot of boilerplate without tie

    my $var = MCE::Shared->share( { module => 'My::Scalar' }, 0 ); $var->set(42)

    And underneath you have locking going on in either case. Is that a correct summary?

    Please note that I really like what you have done with MCE!

      Hello liz,

      Under the hood (MCE::Shared::Server), the boilerplate is the same between OO and TIE for the most part. For Perl-like behavior, the TIE interface involves additional overhead from Perl itself.

      MCE::Mutex is used internally for locking. There are 10 locks, one per data channel. A worker from MCE, MCE::Hobo, or threads is assigned a data-channel automatically in a round-robin fashion. 10 workers max can obtain an exclusive lock simultaneously. The unidirectional command-channel involves no locking.

      Other parallel modules on MetaCPAN may benefit from multiple data channels simply by calling MCE::Shared::init() inside the worker.

      Regards, Mario