Core  3.2
PHP API documentation
 All Data Structures Namespaces Files Functions Variables Pages
parallel.php
Go to the documentation of this file.
1 #!/usr/bin/env php
2 <?php
3 /*
4  * @author Anakeen
5  * @package FDL
6 */
7 /*
8  * Minimal pure-PHP implementation of GNU/parallel
9 */
10 
11 function usage($me)
12 {
13  $usage = <<<EOF
14 
15 Usage
16 -----
17 
18  $me [-j <max_jobs>] [-f <jobs_file>]
19 
20 
21 EOF;
22  print $usage;
23 }
24 
25 function main(&$argv)
26 {
27  $me = array_shift($argv);
28  $maxJobs = 1;
29  $jobsFile = 'php://stdin';
30  while (count($argv) > 0) {
31  $arg = array_shift($argv);
32  switch ($arg) {
33  case '-h':
34  case '--help':
35  usage($me);
36  exit(0);
37  break;
38 
39  case '-j':
40  $maxJobs = array_shift($argv);
41  if ($maxJobs === null) {
42  printf("Missing value after '-j' argument!");
43  usage($me);
44  exit(1);
45  }
46  if ($maxJobs == 'auto') {
47  $maxJobs = getCPUCount();
48  }
49  $maxJobs = (int)(($maxJobs > 0) ? $maxJobs : 1);
50  break;
51 
52  case '-f':
53  $jobsFile = array_shift($argv);
54  if ($jobsFile === null) {
55  printf("Missing file after '-f' argument!");
56  usage($me);
57  exit(1);
58  }
59  if ($jobsFile === '-') {
60  $jobsFile = 'php://stdin';
61  }
62  break;
63 
64  case '--':
65  break 2;
66  default:
67  printf("Unknown argument '%s'.\n", $arg);
68  usage($me);
69  exit(1);
70  }
71  }
72 
73  $commands = file($jobsFile);
74  if ($commands === false) {
75  printf("Error reading content from jobs file '%s'!", $jobsFile);
76  exit(1);
77  }
78 
79  $globalStatus = true;
80  $statusList = array();
81  $runningJobs = array();
82  foreach ($commands as $command) {
83  /* Skip blank lines and (ba)sh comments */
84  if (preg_match('/^\s*(#.*)?$/', $command)) {
85  continue;
86  }
87  while (count($runningJobs) >= $maxJobs) {
88  waitJob($runningJobs, $statusList);
89  }
90  $pid = spawnJob($command);
91  if ($pid === - 1) {
92  printf("Error: spawnJob() returned with unexpected error (running jobs = %d, maxJobs = %d)!", count($runningJobs) , $maxJobs);
93  $globalStatus = false;
94  break;
95  } else {
96  $runningJobs[$pid] = $command;
97  }
98  }
99  while (count($runningJobs) > 0) {
100  waitJob($runningJobs, $statusList);
101  }
102  foreach ($statusList as $status) {
103  $globalStatus&= ($status === 0);
104  }
105  exit($globalStatus ? 0 : 1);
106 }
107 /**
108  * Spawn a new job process to execute the given command and return the job's process pid
109  *
110  * @param $command
111  * @return int
112  */
114 {
115  $pid = pcntl_fork();
116  if ($pid === - 1) {
117  /* Could not fork a new child process */
118  return -1;
119  }
120  if ($pid !== 0) {
121  /* Return the pid to the parent process */
122  return $pid;
123  }
124  /* Execute the command in the new child process */
125  passthru($command, $status);
126  exit($status);
127 }
128 /**
129  * Wait and collect a finished job process
130  *
131  * @param $runningJobs
132  * @param $statusList
133  */
134 function waitJob(&$runningJobs, &$statusList)
135 {
136  /* Wait and collect a finished job */
137  $pid = pcntl_wait($status);
138  if ($pid == - 1) {
139  printf("Error: pcntl_wait() returned with unexpected error!");
140  exit(1);
141  }
142  if (!isset($runningJobs[$pid])) {
143  printf("Weird: process with PID %d (status %d) is not one of my child...\n", $pid, $status);
144  } else {
145  unset($runningJobs[$pid]);
146  $statusList[] = $status;
147  }
148 }
149 /**
150  * Count number of CPUs
151  *
152  * @return int The number of CPUs (0 if number of CPUs could not be detected)
153  */
154 function getCPUCount()
155 {
156  $cpuinfo = @file("/proc/cpuinfo");
157  if ($cpuinfo === false) {
158  return 0;
159  }
160  return array_reduce($cpuinfo, function ($count, $line)
161  {
162  if (preg_match('/^processor\s*:\s*\d+$/', $line)) {
163  $count++;
164  }
165  return $count;
166  }
167  , 0);
168 }
169 
170 main($argv);
$status
Definition: index.php:30
$command
Definition: checkVault.php:34
main(&$argv)
Definition: parallel.php:25
waitJob(&$runningJobs, &$statusList)
Definition: parallel.php:134
spawnJob($command)
Definition: parallel.php:113
usage($me)
Definition: parallel.php:11
print
Definition: checklist.php:49
switch($command) exit
Definition: checkVault.php:46
getCPUCount()
Definition: parallel.php:154
$usage
← centre documentaire © anakeen