g2 Mon Jun 22 00:19:12 2009 UTC
Added files:
/phpruntests/code-samples/taskScheduler/classes
taskSchedulerFile.php
taskSchedulerMsgQ.php
/phpruntests/code-samples/taskScheduler results.xls
Modified files:
/phpruntests/code-samples/taskScheduler/classes taskScheduler.php
/phpruntests/code-samples/taskScheduler run.php
Log:
phpruntests - update taskScheduler (prototype) - added file-driven ipc
http://cvs.php.net/viewvc.cgi/phpruntests/code-samples/taskScheduler/classes/taskScheduler.php?r1=1.2&r2=1.3&diff_format=u
Index: phpruntests/code-samples/taskScheduler/classes/taskScheduler.php
diff -u phpruntests/code-samples/taskScheduler/classes/taskScheduler.php:1.2
phpruntests/code-samples/taskScheduler/classes/taskScheduler.php:1.3
--- phpruntests/code-samples/taskScheduler/classes/taskScheduler.php:1.2
Tue Jun 16 22:43:30 2009
+++ phpruntests/code-samples/taskScheduler/classes/taskScheduler.php Mon Jun
22 00:19:12 2009
@@ -1,24 +1,17 @@
<?php
-declare(ticks=true);
-
-
class taskScheduler
{
- const MSG_QUEUE_KEY = 1234; // id of the message-queue
- const MSG_QUEUE_SIZE = 1024; // max-size of a single message
- const KILL_CHILD = 'killBill'; // kill-signal to terminate a child
-
- private $taskList = array(); // the list of the tasks to be executed
- private $processCount = NULL; // the number of processes
- private $inputQueue = NULL; // the input-queue (only used
by the sender)
- private $pidStore = array(); // stores the pids of all
child-processes
- private $time = 0; // the needed time
- private $countPass = 0; // counts the passed tasks
- private $countFail = 0; // counts the failed tasks
- private $groupTasks = false; // are the tasks stored in groups?
- private $memStore = array(); // stores the mem-usage after an
incomming task
+ protected $taskList = array(); // the list of the tasks to be executed
+ protected $processCount = 0; // the number of processes
+
+ protected $time = 0; // the needed time
+ protected $countPass = 0; // counts the passed tasks
+ protected $countFail = 0; // counts the failed tasks
+ protected $memStore = array(); // stores the mem-usage after an
incomming task
+
+
/**
* the constructor
@@ -34,24 +27,31 @@
$this->setProcessCount($processCount);
}
+
+
+ public static function getInstance(array $taskList=NULL,
$processCount=NUL, $useMsgQ=false)
+ {
+ if (extension_loaded('pcntl')) {
+
+ if ($useMsgQ === true) {
+
+ return new taskSchedulerMsgQ($taskList, $processCount);
+ }
+
+ return new taskSchedulerFile($taskList, $processCount);
+ }
+
+ return new taskScheduler($taskList, $processCount);
+ }
/**
* sets the task-list which has to be an array of task-objects.
- * it's also possible to use a multidimensional array. in this case the
- * tasks are distributed to the child-processes exactly in the way as they
- * are grouped in the list. the first-level index strictly has to be
- * numeric and continuous starting with zero.
- *
+ *
* @param array $taskList
*/
public function setTaskList(array $taskList)
{
- if (is_array($taskList[0])) {
- $this->groupTasks = true;
- $this->processCount = sizeof($taskList);
- }
-
$this->taskList = $taskList;
}
@@ -74,64 +74,18 @@
*/
public function setProcessCount($processCount)
{
- if ($this->groupTasks !== true && is_numeric($processCount) &&
$processCount >= 0) {
+ if (is_numeric($processCount) && $processCount >= 0) {
$this->processCount = $processCount;
}
}
/**
- * removes the used message-queues.
- */
- private static function cleanUp()
- {
- @msg_remove_queue(msg_get_queue(self::MSG_QUEUE_KEY));
- @msg_remove_queue(msg_get_queue(self::MSG_QUEUE_KEY+1));
- logg("CLEAN UP");
- }
-
-
- /**
- * the signal-handler is called by the interrupt- or quit-signal and
calls
- * the cleanUp-method.
- *
- * @param int $signal
- */
- public static function signalHandler($signal)
- {
- logg("SIGNAL: $signal");
-
- switch($signal) {
-
- case SIGINT:
- case SIGQUIT:
- self::cleanUp();
- die("\n");
- break;
-
- default:
- break;
- }
- }
-
- /**
- * switch to run the classic- or the fork-mode
- */
- public function run()
- {
- if ($this->processCount > 0) {
- $this->runFork();
- }
- else $this->runClassic();
- }
-
-
- /**
* executes the tasks in a simple loop
*
* @return void
*/
- private function runClassic()
+ public function run()
{
$s = microtime(true);
@@ -147,6 +101,8 @@
$this->countFail++;
}
+ $this->memStore[] = memory_get_usage(true);
+
print ".";
flush();
@@ -162,256 +118,6 @@
/**
- * starts the sender, the receiver and forks the defined
- * number of child-processes.
- *
- * @return void
- */
- private function runFork()
- {
- $startTime = microtime(true);
-
- // register signal-handler
- pcntl_signal(SIGINT, "taskScheduler::signalHandler");
- pcntl_signal(SIGQUIT, "taskScheduler::signalHandler");
-
- // trim the processCount if nesecarry
- if (is_null($this->processCount) || $this->processCount >
sizeof($this->taskList)) {
- $this->processCount = sizeof($this->taskList);
- }
-
- // fork the child-processes
- for ($i=0; $i<=$this->processCount; $i++) {
-
- $this->pidStore[$i] = pcntl_fork();
-
- switch ($this->pidStore[$i]) {
-
- case -1: // failure
- die("could not fork");
- break;
-
- case 0: // child
- if ($i==0) {
- $this->sender();
- } else {
- $cid = ($this->groupTasks ==
true) ? $i : NULL;
- $this->child($cid);
- }
- break;
-
- default: // parent
- break;
- }
- }
-
- // start the receiver
- $this->receiver();
-
- // wait until all child-processes are terminated
- for ($i=0; $i<=$this->processCount; $i++) {
-
- pcntl_waitpid($this->pidStore[$i], $status);
- logg("child $i terminated - status $status");
- }
-
- $endTime = microtime(true);
- $this->time = round($endTime-$startTime,5);
-
- // remove the msg-queue
- self::cleanUp();
-
- logg("EXIT MAIN");
- return;
- }
-
-
- /**
- * the receiver is listening to the result-queue and stores the
incomming
- * tasks back to the task-list.
- * when finished it sends the kill-signal to all children and terminates
- * itself.
- *
- * @return void
- */
- private function receiver()
- {
- logg("RECEIVER START - ".sizeof($this->taskList)." tasks");
-
- $resultQueue = msg_get_queue(self::MSG_QUEUE_KEY+1);
-
- $task = '';
- $type = 1;
-
- if ($this->groupTasks == true) {
- $limit = 0;
- foreach ($this->taskList as $list) {
- $limit += sizeof($list);
- }
- } else {
- $limit = sizeof($this->taskList);
- }
-
- for ($i=0; $i<$limit; $i++) {
-
- $this->memStore[] = memory_get_usage(true);
-
- if (msg_receive($resultQueue, 0, $type,
self::MSG_QUEUE_SIZE, $task, true, NULL, $error)) {
-
- // check state
- if ($task->getState() == task::PASS) {
- $this->countPass++;
- } else {
- $this->countFail++;
- }
-
- // store result
- $index = $task->getIndex();
-
- if ($this->groupTasks == true) {
- $this->taskList[$type-2][$index] =
$task;
- logg("RECEIVER store task
".($type-1)."-$index");
-
- } else {
- $this->taskList[$index] = $task;
- logg("RECEIVER store task $index");
- }
-
-
- }
- else logg("RECEIVER ERROR $error");
- }
-
- $inputQueue = msg_get_queue(self::MSG_QUEUE_KEY);
-
- for ($i=1; $i<=$this->processCount; $i++) {
-
- if (msg_send($inputQueue, $i, self::KILL_CHILD, true,
true, $error)) {
-
- logg("RECEIVER send KILL_CHILD");
- }
- else logg("RECEIVER ERROR $error");
- }
-
- logg("RECEIVER EXIT");
- return;
- }
-
-
- /**
- * the sender is passes through the task-list and distributes the single
- * tasks to the child-processes using the input-queue.
- * when finished it terminates itself.
- *
- * @return void
- */
- private function sender()
- {
- logg("SENDER START - ".sizeof($this->taskList)." tasks");
-
- $this->inputQueue = msg_get_queue(self::MSG_QUEUE_KEY);
-
- for ($i=0; $i<sizeof($this->taskList); $i++) {
-
- if ($this->groupTasks == true) {
-
- for ($j=0; $j<sizeof($this->taskList[$i]);
$j++) {
-
-
$this->sendTask($this->taskList[$i][$j], $j, $i+1);
- }
-
- } else {
-
- $this->sendTask($this->taskList[$i], $i);
- }
- }
-
- logg("SENDER EXIT");
- exit(0);
- }
-
-
- /**
- * helper-class of sender.
- * sends a task to a child-process using the input-queue.
- *
- * @param task $task the task to send
- * @param int $index the task's index in the taskList
- * @param int $type the message-type (default=1)
- * @return void
- */
- private function sendTask(task $task, $index, $type=1)
- {
- $task->setIndex($index);
-
- if (msg_send($this->inputQueue, $type, $task, true, true,
$error)) {
-
- logg("SENDER send task $type - $index");
- }
- else logg("SENDER ERROR $error");
-
- return;
- }
-
-
- /**
- * the child is listening to the input-queue and executes the incomming
- * tasks. afterwards it setts the task-state and sends it back to the
- * receiver via the result-queue.
- * after receiving the kill-signal from the receiver it terminates
itself.
- *
- * @param int $cid the child-id (default=NULL)
- * @return void
- */
- private function child($cid=NULL)
- {
- if (is_null($cid)) {
- $cid = 0;
- }
-
- logg("child $cid START");
-
- $inputQueue = msg_get_queue(self::MSG_QUEUE_KEY);
- $resultQueue = msg_get_queue(self::MSG_QUEUE_KEY+1);
-
- $type = 1;
-
- while (true) {
-
- if (msg_receive($inputQueue, $cid, $type,
self::MSG_QUEUE_SIZE, $task, true, NULL, $error)) {
-
- if ($task == self::KILL_CHILD)
- break;
-
- $index = $task->getIndex();
-
- logg("child $cid - run task $index");
-
- if ($task->run() === true) {
- $task->setState(task::PASS);
- } else {
- $task->setState(task::FAIL);
- }
-
- print ".";
- flush();
-
- if (msg_send($resultQueue, $cid+1, $task, true,
true, $error)) {
-
- logg("child $cid - send task $index");
- }
- else logg("child $cid ERROR $error");
-
- }
- else logg("child $cid ERROR $error");
- }
-
- logg("child $cid EXIT");
- exit(0);
- }
-
-
- /**
* prints the statistic
*
* @return void
@@ -420,7 +126,7 @@
{
print "\n----------------------------------------\n";
- if ($this->groupTasks == true) {
+ if (is_array($this->taskList[0])) {
$count = 0;
foreach ($this->taskList as $list) {
http://cvs.php.net/viewvc.cgi/phpruntests/code-samples/taskScheduler/run.php?r1=1.2&r2=1.3&diff_format=u
Index: phpruntests/code-samples/taskScheduler/run.php
diff -u phpruntests/code-samples/taskScheduler/run.php:1.2
phpruntests/code-samples/taskScheduler/run.php:1.3
--- phpruntests/code-samples/taskScheduler/run.php:1.2 Tue Jun 16 22:43:30 2009
+++ phpruntests/code-samples/taskScheduler/run.php Mon Jun 22 00:19:12 2009
@@ -1,6 +1,8 @@
<?php
include 'classes/taskScheduler.php';
+include 'classes/taskSchedulerMsgQ.php';
+include 'classes/taskSchedulerFile.php';
include 'classes/taskInterface.php';
include 'classes/task.php';
@@ -25,14 +27,15 @@
$argc = sizeof($argv);
-if ($argc >= 2 || $argc <= 3) {
+if ($argc >= 2 || $argc <= 4) {
$src = $argv[1];
$count = isset($argv[2]) ? $argv[2] : NULL;
+ $useMsgQ = isset($argv[3]);
} else {
- die("USAGE: php run.php example processCount\n");
+ die("USAGE: php run.php example processCount useMsgQ\n");
}
@@ -50,20 +53,21 @@
$taskList = createTaskList($count);
+
// init scheduler
-$c = new taskScheduler();
+$c = taskScheduler::getInstance($taskList, $count, $useMsgQ);
+
$c->setTaskList($taskList);
$c->setProcessCount($count);
$c->run();
-$c->printStatistic();
-
-// var_dump($c->getTaskList());
+$c->printStatistic();
$c->printFailedTasks();
-
$c->printMemStatistic(10);
+// var_dump($c->getTaskList());
+
exit(0);
?>
http://cvs.php.net/viewvc.cgi/phpruntests/code-samples/taskScheduler/classes/taskSchedulerFile.php?view=markup&rev=1.1
Index: phpruntests/code-samples/taskScheduler/classes/taskSchedulerFile.php
+++ phpruntests/code-samples/taskScheduler/classes/taskSchedulerFile.php
<?php
class taskSchedulerFile extends taskScheduler
{
const TMP_FILE = 'taskFile';
private $inputQueue = NULL; // the input-queue (only used
by the sender)
private $pidStore = array(); // stores the pids of all
child-processes
private $groupTasks = false; // are the tasks stored in groups?
private $tmpTaskList = array();
/**
* the constructor
*
* @param array $taskList (optional)
* @param int $processCount (optional)
*/
public function __construct(array $taskList=NULL, $processCount=NULL)
{
if (is_array($taskList)) {
$this->setTaskList($taskList);
}
$this->setProcessCount($processCount);
}
/**
* sets the task-list which has to be an array of task-objects.
* it's also possible to use a multidimensional array. in this case the
* tasks are distributed to the child-processes exactly in the way as they
* are grouped in the list. the first-level index strictly has to be
* numeric and continuous starting with zero.
*
* @param array $taskList
* @Overrides
*/
public function setTaskList(array $taskList)
{
if (is_array($taskList[0])) {
$this->groupTasks = true;
$this->processCount = sizeof($taskList);
}
$this->taskList = $taskList;
}
/**
* sets the number of child-processes.
* in the case of using a multidimensional task-list this parameter is
* ignored and set to the number of task-groups.
*
* @param int $count
* @Overrides
*/
public function setProcessCount($processCount)
{
if ($this->groupTasks !== true && is_numeric($processCount) &&
$processCount >= 0) {
$this->processCount = $processCount;
}
}
/**
* starts the sender, the receiver and forks the defined
* number of child-processes.
*
* @return void
* @Overrides
*/
public function run()
{
if ($this->processCount == 0) {
return parent::run();
}
$startTime = microtime(true);
// trim the processCount if nesecarry
if ($this->processCount > sizeof($this->taskList)) {
$this->processCount = sizeof($this->taskList);
}
$this->createTaskFiles();
// fork the child-processes
for ($i=1; $i<=$this->processCount; $i++) {
$this->pidStore[$i] = pcntl_fork();
switch ($this->pidStore[$i]) {
case -1: // failure
die("could not fork");
break;
case 0: // child
$this->child($i-1);
break;
default: // parent
break;
}
}
// wait until all child-processes are terminated
for ($i=0; $i<$this->processCount; $i++) {
pcntl_waitpid($this->pidStore[$i], $status);
logg("child $i terminated - status $status");
}
// ensure that the tmp-files are completly written
sleep(1);
// collecting the results
$this->receiver($i);
$endTime = microtime(true);
$this->time = round($endTime-$startTime,5);
logg("EXIT MAIN");
return;
}
/**
* creates a temporary file for each child which stores the allocated
* array-indices.
*
*/
private function createTaskFiles() {
$taskStr = array();
if ($this->groupTasks == true) {
$c = 0;
foreach ($this->taskList as $key => $list) {
for ($i=0; $i<sizeof($list); $i++) {
$taskStr[$key] .= $i.';';
}
}
} else {
for ($i=0; $i<sizeof($this->taskList); $i++) {
$taskStr[$i%$this->processCount] .= $i.';';
}
}
for ($i=0; $i<$this->processCount; $i++) {
file_put_contents(self::TMP_FILE.$i, $taskStr[$i]);
}
}
/**
* @return void
*/
private function receiver()
{
logg("RECEIVER START");
for ($cid=0; $cid<$this->processCount; $cid++) {
$response = file_get_contents(self::TMP_FILE.$cid);
$response = explode("\n", $response);
array_pop($response);
foreach ($response as $task) {
$task = unserialize($task);
if ($task->getState() == task::PASS) {
$this->countPass++;
} else {
$this->countFail++;
}
$index = $task->getIndex();
if ($this->groupTasks == true) {
$this->taskList[$cid][$index] = $task;
} else {
$this->taskList[$index] = $task;
}
}
unlink(self::TMP_FILE.$cid);
}
return;
}
/**
* @param int $cid the child-id
* @return void
*/
private function child($cid)
{
logg("child $cid START");
$indexList = file_get_contents(self::TMP_FILE.$cid);
$indexList = explode(';', $indexList);
array_pop($indexList);
$response = '';
foreach ($indexList as $index) {
logg("child $cid - run task $index");
if ($this->groupTasks == true) {
$task = $this->taskList[$cid][$index];
} else {
$task = $this->taskList[$index];
}
if ($task->run() === true) {
$task->setState(task::PASS);
} else {
$task->setState(task::FAIL);
}
$task->setIndex($index);
print ".";
flush();
$response .= serialize($task)."\n";
}
file_put_contents(self::TMP_FILE.$cid, $response, LOCK_EX);
logg("child $cid EXIT");
exit(0);
}
/**
* prints the statistic
*
* @return void
*/
public function printStatistic()
{
print "\n----------------------------------------\n";
if (is_array($this->taskList[0])) {
$count = 0;
foreach ($this->taskList as $list) {
$count += sizeof($list);
}
print "Groups:\t\t".sizeof($this->taskList)."\n";
print "Tasks:\t\t".$count."\n";
} else {
$count = sizeof($this->taskList);
print "Tasks:\t\t".$count."\n";
}
print "PASSED:\t\t".$this->countPass."
(".round($this->countPass/$count*100,2)."%)\n";
print "FAILED:\t\t".$this->countFail."
(".round($this->countFail/$count*100,2)."%)\n";
print "Processes:\t".$this->processCount."\n";
print "Seconds:\t".$this->time."\n";
print "----------------------------------------\n";
flush();
}
public function printMemStatistic($int=10) {}
}
?>
http://cvs.php.net/viewvc.cgi/phpruntests/code-samples/taskScheduler/classes/taskSchedulerMsgQ.php?view=markup&rev=1.1
Index: phpruntests/code-samples/taskScheduler/classes/taskSchedulerMsgQ.php
+++ phpruntests/code-samples/taskScheduler/classes/taskSchedulerMsgQ.php
<?php
declare(ticks=true);
class taskSchedulerMsgQ extends taskScheduler
{
const MSG_QUEUE_KEY = 1234; // id of the message-queue
const MSG_QUEUE_SIZE = 1024; // max-size of a single message
const KILL_CHILD = 'killBill'; // kill-signal to terminate a child
private $inputQueue = NULL; // the input-queue (only used
by the sender)
private $pidStore = array(); // stores the pids of all
child-processes
private $groupTasks = false; // are the tasks stored in groups?
/**
* sets the task-list which has to be an array of task-objects.
* it's also possible to use a multidimensional array. in this case the
* tasks are distributed to the child-processes exactly in the way as they
* are grouped in the list. the first-level index strictly has to be
* numeric and continuous starting with zero.
*
* @param array $taskList
* @Overrides
*/
public function setTaskList(array $taskList)
{
if (is_array($taskList[0])) {
$this->groupTasks = true;
$this->processCount = sizeof($taskList);
}
$this->taskList = $taskList;
}
/**
* sets the number of child-processes.
* in the case of using a multidimensional task-list this parameter is
* ignored and set to the number of task-groups.
*
* @param int $count
* @Overrides
*/
public function setProcessCount($processCount)
{
if ($this->groupTasks !== true && is_numeric($processCount) &&
$processCount >= 0) {
$this->processCount = $processCount;
}
}
/**
* removes the used message-queues.
*/
private static function cleanUp()
{
@msg_remove_queue(msg_get_queue(self::MSG_QUEUE_KEY));
@msg_remove_queue(msg_get_queue(self::MSG_QUEUE_KEY+1));
logg("CLEAN UP");
}
/**
* the signal-handler is called by the interrupt- or quit-signal and
calls
* the cleanUp-method.
*
* @param int $signal
*/
public static function signalHandler($signal)
{
logg("SIGNAL: $signal");
switch($signal) {
case SIGINT:
case SIGQUIT:
self::cleanUp();
die("\n");
break;
default:
break;
}
}
/**
* starts the sender, the receiver and forks the defined
* number of child-processes.
*
* @return void
* @Overrides
*/
public function run()
{
if ($this->processCount == 0) {
return parent::run();
}
$startTime = microtime(true);
// register signal-handler
pcntl_signal(SIGINT, "taskSchedulerMsgQ::signalHandler");
pcntl_signal(SIGQUIT, "taskSchedulerMsgQ::signalHandler");
// trim the processCount if nesecarry
if ($this->processCount > sizeof($this->taskList)) {
$this->processCount = sizeof($this->taskList);
}
// fork the child-processes
for ($i=0; $i<=$this->processCount; $i++) {
$this->pidStore[$i] = pcntl_fork();
switch ($this->pidStore[$i]) {
case -1: // failure
die("could not fork");
break;
case 0: // child
if ($i==0) {
$this->sender();
} else {
$cid = ($this->groupTasks ==
true) ? $i : NULL;
$this->child($cid);
}
break;
default: // parent
break;
}
}
// start the receiver
$this->receiver();
// wait until all child-processes are terminated
for ($i=0; $i<=$this->processCount; $i++) {
pcntl_waitpid($this->pidStore[$i], $status);
logg("child $i terminated - status $status");
}
$endTime = microtime(true);
$this->time = round($endTime-$startTime,5);
// remove the msg-queue
self::cleanUp();
logg("EXIT MAIN");
return;
}
/**
* the receiver is listening to the result-queue and stores the
incomming
* tasks back to the task-list.
* when finished it sends the kill-signal to all children and terminates
* itself.
*
* @return void
*/
private function receiver()
{
logg("RECEIVER START - ".sizeof($this->taskList)." tasks");
$resultQueue = msg_get_queue(self::MSG_QUEUE_KEY+1);
$task = '';
$type = 1;
if ($this->groupTasks == true) {
$limit = 0;
foreach ($this->taskList as $list) {
$limit += sizeof($list);
}
} else {
$limit = sizeof($this->taskList);
}
for ($i=0; $i<$limit; $i++) {
$this->memStore[] = memory_get_usage(true);
if (msg_receive($resultQueue, 0, $type,
self::MSG_QUEUE_SIZE, $task, true, NULL, $error)) {
// check state
if ($task->getState() == task::PASS) {
$this->countPass++;
} else {
$this->countFail++;
}
// store result
$index = $task->getIndex();
if ($this->groupTasks == true) {
$this->taskList[$type-2][$index] =
$task;
logg("RECEIVER store task
".($type-1)."-$index");
} else {
$this->taskList[$index] = $task;
logg("RECEIVER store task $index");
}
}
else logg("RECEIVER ERROR $error");
}
$inputQueue = msg_get_queue(self::MSG_QUEUE_KEY);
for ($i=1; $i<=$this->processCount; $i++) {
if (msg_send($inputQueue, $i, self::KILL_CHILD, true,
true, $error)) {
logg("RECEIVER send KILL_CHILD");
}
else logg("RECEIVER ERROR $error");
}
logg("RECEIVER EXIT");
return;
}
/**
* the sender is passes through the task-list and distributes the single
* tasks to the child-processes using the input-queue.
* when finished it terminates itself.
*
* @return void
*/
private function sender()
{
logg("SENDER START - ".sizeof($this->taskList)." tasks");
$this->inputQueue = msg_get_queue(self::MSG_QUEUE_KEY);
for ($i=0; $i<sizeof($this->taskList); $i++) {
if ($this->groupTasks == true) {
for ($j=0; $j<sizeof($this->taskList[$i]);
$j++) {
$this->sendTask($this->taskList[$i][$j], $j, $i+1);
}
} else {
$this->sendTask($this->taskList[$i], $i);
}
}
logg("SENDER EXIT");
exit(0);
}
/**
* helper-class of sender.
* sends a task to a child-process using the input-queue.
*
* @param task $task the task to send
* @param int $index the task's index in the taskList
* @param int $type the message-type (default=1)
* @return void
*/
private function sendTask(task $task, $index, $type=1)
{
$task->setIndex($index);
if (msg_send($this->inputQueue, $type, $task, true, true,
$error)) {
logg("SENDER send task $type - $index");
}
else logg("SENDER ERROR $error");
return;
}
/**
* the child is listening to the input-queue and executes the incomming
* tasks. afterwards it setts the task-state and sends it back to the
* receiver via the result-queue.
* after receiving the kill-signal from the receiver it terminates
itself.
*
* @param int $cid the child-id (default=NULL)
* @return void
*/
private function child($cid=NULL)
{
if (is_null($cid)) {
$cid = 0;
}
logg("child $cid START");
$inputQueue = msg_get_queue(self::MSG_QUEUE_KEY);
$resultQueue = msg_get_queue(self::MSG_QUEUE_KEY+1);
$type = 1;
while (true) {
if (msg_receive($inputQueue, $cid, $type,
self::MSG_QUEUE_SIZE, $task, true, NULL, $error)) {
if ($task == self::KILL_CHILD)
break;
$index = $task->getIndex();
logg("child $cid - run task $index");
if ($task->run() === true) {
$task->setState(task::PASS);
} else {
$task->setState(task::FAIL);
}
print ".";
flush();
if (msg_send($resultQueue, $cid+1, $task, true,
true, $error)) {
logg("child $cid - send task $index");
}
else logg("child $cid ERROR $error");
}
else logg("child $cid ERROR $error");
}
logg("child $cid EXIT");
exit(0);
}
}
?>
http://cvs.php.net/viewvc.cgi/phpruntests/code-samples/taskScheduler/results.xls?view=markup&rev=1.1
Index: phpruntests/code-samples/taskScheduler/results.xls
+++ phpruntests/code-samples/taskScheduler/results.xls
ÐÏࡱá
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.print.PageFormat.PMHorizontalRes</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMHorizontalRes</key>
<real>300</real>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PageFormat.PMOrientation</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMOrientation</key>
<integer>1</integer>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PageFormat.PMScaling</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMScaling</key>
<real>1</real>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PageFormat.PMVerticalRes</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMVerticalRes</key>
<real>300</real>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PageFormat.PMVerticalScaling</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMVerticalScaling</key>
<real>1</real>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.subTicket.paper_info_ticket</key>
<dict>
<key>PMPPDPaperCodeName</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>PMPPDPaperCodeName</key>
<string>A4</string>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>PMTiogaPaperName</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>PMTiogaPaperName</key>
<string>iso-a4</string>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PageFormat.PMAdjustedPageRect</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMAdjustedPageRect</key>
<array>
<real>0.0</real>
<real>0.0</real>
<real>3262.5000000000005</real>
<real>2329.166666666667</real>
</array>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PageFormat.PMAdjustedPaperRect</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMAdjustedPaperRect</key>
<array>
<real>-75</real>
<real>-75</real>
<real>3433.3333333333335</real>
<real>2404.166666666667</real>
</array>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PaperInfo.PMPaperName</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PaperInfo.PMPaperName</key>
<string>iso-a4</string>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PaperInfo.PMUnadjustedPageRect</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PaperInfo.PMUnadjustedPageRect</key>
<array>
<real>0.0</real>
<real>0.0</real>
<real>783</real>
<real>559</real>
</array>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PaperInfo.PMUnadjustedPaperRect</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PaperInfo.PMUnadjustedPaperRect</key>
<array>
<real>-18</real>
<real>-18</real>
<real>824</real>
<real>577</real>
</array>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PaperInfo.ppd.PMPaperName</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PaperInfo.ppd.PMPaperName</key>
<string>A4</string>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.ticket.APIVersion</key>
<string>00.20</string>
<key>com.apple.print.ticket.type</key>
<string>com.apple.print.PaperInfoTicket</string>
</dict>
<key>com.apple.print.ticket.APIVersion</key>
<string>00.20</string>
<key>com.apple.print.ticket.type</key>
<string>com.apple.print.PageFormatTicket</string>
</dict>
</plist>
M
&
ý
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.print.PageFormat.PMHorizontalRes</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMHorizontalRes</key>
<real>300</real>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PageFormat.PMOrientation</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMOrientation</key>
<integer>1</integer>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PageFormat.PMScaling</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMScaling</key>
<real>1</real>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PageFormat.PMVerticalRes</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMVerticalRes</key>
<real>300</real>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PageFormat.PMVerticalScaling</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMVerticalScaling</key>
<real>1</real>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.subTicket.paper_info_ticket</key>
<dict>
<key>PMPPDPaperCodeName</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>PMPPDPaperCodeName</key>
<string>A4</string>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>PMTiogaPaperName</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>PMTiogaPaperName</key>
<string>iso-a4</string>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PageFormat.PMAdjustedPageRect</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMAdjustedPageRect</key>
<array>
<real>0.0</real>
<real>0.0</real>
<real>3262.5000000000005</real>
<real>2329.166666666667</real>
</array>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PageFormat.PMAdjustedPaperRect</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMAdjustedPaperRect</key>
<array>
<real>-75</real>
<real>-75</real>
<real>3433.3333333333335</real>
<real>2404.166666666667</real>
</array>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PaperInfo.PMPaperName</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PaperInfo.PMPaperName</key>
<string>iso-a4</string>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PaperInfo.PMUnadjustedPageRect</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PaperInfo.PMUnadjustedPageRect</key>
<array>
<real>0.0</real>
<real>0.0</real>
<real>783</real>
<real>559</real>
</array>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PaperInfo.PMUnadjustedPaperRect</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PaperInfo.PMUnadjustedPaperRect</key>
<array>
<real>-18</real>
<real>-18</real>
<real>824</real>
<real>577</real>
</array>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PaperInfo.ppd.PMPaperName</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PaperInfo.ppd.PMPaperName</key>
<string>A4</string>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.ticket.APIVersion</key>
<string>00.20</string>
<key>com.apple.print.ticket.type</key>
<string>com.apple.print.PaperInfoTicket</string>
</dict>
<key>com.apple.print.ticket.APIVersion</key>
<string>00.20</string>
<key>com.apple.print.ticket.type</key>
<string>com.apple.print.PageFormatTicket</string>
</dict>
</plist>
M
&
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.print.PageFormat.PMHorizontalRes</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMHorizontalRes</key>
<real>300</real>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PageFormat.PMOrientation</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMOrientation</key>
<integer>1</integer>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PageFormat.PMScaling</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMScaling</key>
<real>1</real>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PageFormat.PMVerticalRes</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMVerticalRes</key>
<real>300</real>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PageFormat.PMVerticalScaling</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMVerticalScaling</key>
<real>1</real>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.subTicket.paper_info_ticket</key>
<dict>
<key>PMPPDPaperCodeName</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>PMPPDPaperCodeName</key>
<string>A4</string>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>PMTiogaPaperName</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>PMTiogaPaperName</key>
<string>iso-a4</string>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PageFormat.PMAdjustedPageRect</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMAdjustedPageRect</key>
<array>
<real>0.0</real>
<real>0.0</real>
<real>3262.5000000000005</real>
<real>2329.166666666667</real>
</array>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PageFormat.PMAdjustedPaperRect</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PageFormat.PMAdjustedPaperRect</key>
<array>
<real>-75</real>
<real>-75</real>
<real>3433.3333333333335</real>
<real>2404.166666666667</real>
</array>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PaperInfo.PMPaperName</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PaperInfo.PMPaperName</key>
<string>iso-a4</string>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PaperInfo.PMUnadjustedPageRect</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PaperInfo.PMUnadjustedPageRect</key>
<array>
<real>0.0</real>
<real>0.0</real>
<real>783</real>
<real>559</real>
</array>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PaperInfo.PMUnadjustedPaperRect</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PaperInfo.PMUnadjustedPaperRect</key>
<array>
<real>-18</real>
<real>-18</real>
<real>824</real>
<real>577</real>
</array>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.PaperInfo.ppd.PMPaperName</key>
<dict>
<key>com.apple.print.ticket.creator</key>
<string>com.apple.jobticket</string>
<key>com.apple.print.ticket.itemArray</key>
<array>
<dict>
<key>com.apple.print.PaperInfo.ppd.PMPaperName</key>
<string>A4</string>
<key>com.apple.print.ticket.stateFlag</key>
<integer>0</integer>
</dict>
</array>
</dict>
<key>com.apple.print.ticket.APIVersion</key>
<string>00.20</string>
<key>com.apple.print.ticket.type</key>
<string>com.apple.print.PaperInfoTicket</string>
</dict>
<key>com.apple.print.ticket.APIVersion</key>
<string>00.20</string>
<key>com.apple.print.ticket.type</key>
<string>com.apple.print.PageFormatTicket</string>
</dict>
</plist>
M
&
ÿÿ
ÿ
cRZÖÿNsJRZÖNsF1ÿZÖþg9ÿNsùÿNsÿ
F1ÿ
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php