in reply to Re^2: A new CB reader
in thread A new CB reader

Hi Discipulus. Just few line changes ( 3 places ). Here's the diff output.

$ diff pm-cb-g pm-cb-g-hobo 27,28c27,28 < use threads (stack_size => 2 ** $stack_size); < use Thread::Queue; --- > use MCE::Hobo; > use MCE::Shared; 41c41 < my ($readQ, $writeQ) = map 'Thread::Queue'->new, 1, 2; --- > my ($readQ, $writeQ) = map { MCE::Shared->queue() } 1, 2; 43c43 < my $communicate_t = threads->create(\&communicate); --- > my $communicate_t = MCE::Hobo->create(\&communicate);

Update. The stack_size option isn't needed when using MCE::Hobo. Below is the diff -u output.

$ diff -u pm-cb-g pm-cb-g-hobo --- pm-cb-g 2017-07-07 16:05:39.000000000 -0500 +++ pm-cb-g-hobo 2017-07-07 16:32:36.782646208 -0500 @@ -6,12 +6,11 @@ use Getopt::Long qw( :config no_ignore_case ); -my ($bg_color, $fg_color, $author_color, $font_name, $char_size, - $stack_size); +my ($bg_color, $fg_color, $author_color, $font_name, $char_size); BEGIN { ($bg_color, $fg_color, $author_color, $font_name, $char_size, - $stack_size) = qw( white black blue Helvetica 12 15 ); + ) = qw( white black blue Helvetica 12 ); die "Invalid arguments!\n" unless GetOptions( 'a|author_color=s' => \$author_color, @@ -19,13 +18,12 @@ 'c|char_size=i' => \$char_size, 'f|fg_color=s' => \$fg_color, 'F|font_name=s' => \$font_name, - 's|stack_size=i' => \$stack_size, ); } -use threads (stack_size => 2 ** $stack_size); -use Thread::Queue; +use MCE::Hobo; +use MCE::Shared; use constant { @@ -38,9 +36,9 @@ }; -my ($readQ, $writeQ) = map 'Thread::Queue'->new, 1, 2; +my ($readQ, $writeQ) = map { MCE::Shared->queue() } 1, 2; -my $communicate_t = threads->create(\&communicate); +my $communicate_t = MCE::Hobo->create(\&communicate); gui();

Regards, Mario

Replies are listed 'Best First'.
Re^4: A new CB reader
by marioroy (Prior) on Jul 11, 2019 at 01:26 UTC

    Update: Made a fork so not having to apply the diff by hand if wanting to try https://github.com/marioroy/pm-cb. The only benefit to using MCE::Child and MCE::Channel is that there is one less process on Unix platforms (i.e. no shared-manager process). choroba, please know that it is okay to reject this. I made a fork simply to test pm-cb-g using MCE::Child and MCE::Channel for my own validation.

    Hi,

    I released MCE 1.841 (includes MCE::Channel and MCE::Child) and MCE::Shared 1.841. During development, ran pm-cb-g using MCE::Child and MCE::Channel on my laptop (macOS) including a Windows 7 VM. Here is the diff output (long form).

    diff -aur pm-cb-master/lib/PM/CB/Control.pm pm-cb-master2/lib/PM/CB/Co +ntrol.pm --- pm-cb-master/lib/PM/CB/Control.pm 2019-06-08 16:07:06.000000000 + -0400 +++ pm-cb-master2/lib/PM/CB/Control.pm 2019-07-10 22:40:18.00000000 +0 -0400 @@ -15,6 +15,9 @@ sub start_comm { my ($self) = @_; $self->{communicate_t} = $self->{worker_class}->create(sub { + if ($INC{'threads.pm'}) { + $SIG{QUIT} = sub { threads->exit }; + } my $communication = PM::CB::Communication->new({ to_gui => $self->{to_gui}, from_gui => $self->{to_comm}, @@ -42,9 +45,11 @@ $self->{to_comm}->enqueue(['url']); }; } - $self->{to_comm}->insert(0, ['quit']); - $self->{communicate_t}->join; - $self->{to_gui}->insert(0, ['quit']); + if ($^O ne 'MSWin32' || ! $INC{'MCE/Util.pm'}) { + $self->{communicate_t}->kill('QUIT'); + $self->{communicate_t}->join; + } + $self->{to_gui}->enqueue(['quit']); } diff -aur pm-cb-master/lib/PM/CB/GUI.pm pm-cb-master2/lib/PM/CB/GUI.pm --- pm-cb-master/lib/PM/CB/GUI.pm 2019-06-08 16:07:06.000000000 -04 +00 +++ pm-cb-master2/lib/PM/CB/GUI.pm 2019-07-06 15:17:07.000000000 -0 +400 @@ -673,7 +673,7 @@ sub quit { my ($self) = @_; print STDERR "Quitting...\n"; - $self->{to_control}->insert(0, ['quit']); + $self->{to_control}->enqueue(['quit']); } diff -aur pm-cb-master/pm-cb-g pm-cb-master2/pm-cb-g --- pm-cb-master/pm-cb-g 2019-06-08 16:07:06.000000000 -0400 +++ pm-cb-master2/pm-cb-g 2019-07-06 15:11:58.000000000 -0400 @@ -55,15 +55,15 @@ } -use if $mce => 'MCE::Hobo'; -use if $mce => 'MCE::Shared'; +use if $mce => 'MCE::Child'; +use if $mce => 'MCE::Channel'; use if ! $mce => threads => (stack_size => 2 ** $stack_size); use if ! $mce => 'Thread::Queue'; my ($queue_class, $queue_constructor, $worker_class) = $mce - ? ('MCE::Shared', 'queue', 'MCE::Hobo') + ? ('MCE::Channel', 'new', 'MCE::Child') : ('Thread::Queue', 'new', 'threads'); my ($to_gui, $to_comm, $to_control)

    The ->insert method is lacking in MCE::Channel due to an edge case so not implemented. Signaling workers is another way and works well using threads on Windows, MCE::Hobo or MCE::Child on Unix. Threads requires one to define the signal handler whereas MCE::Hobo and MCE::Child already configure $SIG{QUIT} to terminate.

    Update: I needed to enclose two lines above inside an if statement due to signal handling delayed for child processes (emulated) on the Windows platform. Perhaps the Tk loop is preventlng signaling from happening, am not sure. Tested the update on macOS and WIndows with and without the -m command-line switch.

    + if ( $^O ne 'MSWin32' || ! $INC{'MCE/Child.pm'} ) { + $self->{communicate_t}->kill('QUIT'); + $self->{communicate_t}->join; + }

    Q. Why does MCE::Channel lack the insert method?

    A. Unlike MCE::Shared->queue, there is no manager process involvement in MCE::Channel. Thus, a worker holding a read lock on an empty channel (awaiting next item) makes it impossible for another worker inserting. Enqueue involves write lock only, but insert requires both read and write locks.

    Regards, Mario

      Here is the smaller diff output (short form) for using MCE::Child and MCE::Channel. There is no involvment of the separate shared-manager process or thread due to not using MCE::Shared.

      diff -r pm-cb-master/lib/PM/CB/Control.pm pm-cb-master2/lib/PM/CB/Cont +rol.pm 17a18,20 > if ($INC{'threads.pm'}) { > $SIG{QUIT} = sub { threads->exit }; > } 45,47c48,52 < $self->{to_comm}->insert(0, ['quit']); < $self->{communicate_t}->join; < $self->{to_gui}->insert(0, ['quit']); --- > if ($^O ne 'MSWin32' || ! $INC{'MCE/Util.pm'}) { > $self->{communicate_t}->kill('QUIT'); > $self->{communicate_t}->join; > } > $self->{to_gui}->enqueue(['quit']); diff -r pm-cb-master/lib/PM/CB/GUI.pm pm-cb-master2/lib/PM/CB/GUI.pm 676c676 < $self->{to_control}->insert(0, ['quit']); --- > $self->{to_control}->enqueue(['quit']); diff -r pm-cb-master/pm-cb-g pm-cb-master2/pm-cb-g 58,59c58,59 < use if $mce => 'MCE::Hobo'; < use if $mce => 'MCE::Shared'; --- > use if $mce => 'MCE::Child'; > use if $mce => 'MCE::Channel'; 66c66 < ? ('MCE::Shared', 'queue', 'MCE::Hobo') --- > ? ('MCE::Channel', 'new', 'MCE::Child')

      Regards, Mario

        All of your changes have been merged to my fork of pm-cb, which supports config files ($HOME/pm-cb.rc, $HOME/.pm-cbrc and/or $HOME/.config/pm-cb)


        Enjoy, Have FUN! H.Merijn