Problem with multiple perl tasks

I ended my earlier multithreaded program that uses perl threads and it works on my system. The problem is that on some systems that need to be launched, thread support does not compile in perl, and I cannot install additional packages. So I need to use something other than threads, and I move on to my code to use fork (). This works on my Windows system when running subtasks.

A few problems:

  • How to determine when a child process ends? I created new threads, when the number of threads was below a certain value, I need to track how many threads are working. For processes, how do I know when one of them exits, so I can track how many of them exist at that time, increasing the counter when creating and decreasing when exiting it?

  • Is file I / O using descriptors obtained with OPEN when it is opened by a safe parent process in a child process? I need to add to the file for each of the child processes, it is safe for unix as well.

  • Is there an alternative to plugs and threads? I tried using Parallel :: ForkManager, but it is not installed on my system (use Parallel :: ForkManager; gave an error), and I absolutely require my perl script to work on all unix / windows systems without installing any additional modules.

+4
source share
2 answers

Typical Usage:

use POSIX ':sys_wait_h'; # for &WNOHANG # how to create a new background process $pid = fork(); if (!defined $pid) { die "fork() failed!" } if ($pid == 0) { # child # ... do stuff in background ... exit 0; # don't forget to exit or die from the child process } # else this is the parent, $pid contains process id of child process # ... do stuff in foreground ... # how to tell if a process is finished # also see perldoc perlipc $pid = waitpid -1, 0; # blocking wait for any process $pid = wait; # blocking wait for any process $pid = waitpid $mypid, 0; # blocking wait for process $mypid # after blocking wait/waitpid if ($pid == -1) { print "All child processes are finished.\n"; } else { print "Process $pid is finished.\n"; print "The exit status of process $pid was $?\n"; } $pid = waitpid -1, &WNOHANG; # non-blocking wait for any process $pid = waitpid $mypid, 0; # blocking wait for process $mypid if ($pid == -1) { print "No child processes have finished since last wait/waitpid call.\n"; } else { print "Process $pid is finished.\n"; print "The exit status of process $pid was $?\n"; } # terminating a process - see perldoc -f kill or perldoc perlipc # this can be flaky on Windows kill 'INT', $pid; # send SIGINT to process $pid 

Mountain information in perldoc -f fork , waitpid , wait , kill , and perlipc . The material in perlipc about setting up the SIGCHLD event handler should be especially useful, although this is not supported on Windows.

Branched-process I / O is generally safe for Unix and Windows. File descriptors are split, so for something like this

 open X, ">", $file; if (fork() == 0) { # in child print X "Child\n"; close X; exit 0; } # in parent sleep 1; print X "Parent\n"; close X; 

both child and parent processes will be successfully written to the same file (however, be sure to buffer output).

+6
source

Take a look at waitpid . Here is some code that should do nine tasks (1 to 9). To complete these tasks, he will launch up to three workers.

 #!/usr/bin/perl use strict; use warnings; use POSIX ":sys_wait_h"; my $max_children = 3; my %work = map { $_ => 1 } 1 .. 9; my @work = keys %work; my %pids; while (%work) { #while there are still empty slots while (@work and keys %pids < $max_children) { #get some work for the child to do my $work = shift @work; die "could not fork" unless defined(my $pid = fork); #parent if ($pid) { $pids{$pid} = 1; next; } #child print "$$ doing work $work\n"; sleep 1; print "$$ done doing work $work"; exit $work; } my $pid = waitpid -1, WNOHANG; if ($pid > 0) { delete $pids{$pid}; my $rc = $? >> 8; #get the exit status print "saw $pid was done with $rc\n"; delete $work{$rc}; print "work left: ", join(", ", sort keys %work), "\n"; } select undef, undef, undef, .25; } 
+3
source

Source: https://habr.com/ru/post/1313133/


All Articles