(First problem is below)
Finally made it like i wanted ! What a headache ^^
Not using pool was the answer ;)
So, here is my code, output below !
As you can see on the output, i got my jobs distribute evenly between workers 1 & 2 while worker 0 is running a long job !
<?php
class ChildThread extends Threaded {
public $workerId;
protected $complete;
public function __construct($workerId){
// init some properties
$this->workerId = $workerId;
$this->complete = false;
}
public function run(){
// do some work
echo " STARTING " . $this->workerId . "\r\n";
if($this->workerId == 0){
sleep(10);
} else {
sleep(1);
}
echo " ENDING " . $this->workerId . "\r\n";
$this->complete = true;
}
public function isComplete() {
return $this->complete;
}
}
$WORKER_COUNT = 3;
$workers = array();
for ($i=0; $i<$WORKER_COUNT; $i++) {
$worker = new Worker();
$worker->start();
$workers[] = $worker;
}
$tasks = array();
//Create 9 jobs
for ($i=0; $i < 9; $i++) {
$tasks[] = new ChildThread($i);
}
$cptTasks = 0;
//References for running jobs
$taskss = array();
while(count($tasks) > 0){
foreach ($workers as $key => $worker) {
if($worker->isShutdown()){
echo "Shutdowned worker ".$key.", restarting it !"."\r\n";
$worker->start();
}
//If worker is free of charge
if($worker->isWorking() === false ){
//Check if task not null
if(isset($tasks[$cptTasks])){
echo ("Stacking job ".$cptTasks." on worker ".$key."\r\n");
$worker->stack($tasks[$cptTasks]);
$taskss[] = $tasks[$cptTasks];
//Clear job from jobs list
unset($tasks[$cptTasks]);
$cptTasks++;
}
}
}
usleep(2000);
}
//Clear workers
foreach ($workers as $key => $worker) {
echo "Shutdown worker : " .$key."\r\n";
$worker->shutdown();
}
?>
Output :
Stacking job 0 on worker 0
Stacking job 1 on worker 1
Stacking job 2 on worker 2
STARTING 1
STARTING 0
STARTING 2
ENDING 1
ENDING 2
Stacking job 3 on worker 1
Stacking job 4 on worker 2
STARTING 3
STARTING 4
ENDING 3
ENDING 4
Stacking job 5 on worker 1
Stacking job 6 on worker 2
STARTING 5
STARTING 6
ENDING 5
ENDING 6
Stacking job 7 on worker 1
Stacking job 8 on worker 2
STARTING 7
STARTING 8
Shutdown worker : 0
ENDING 8
ENDING 7
ENDING 0
Shutdown worker : 1
Shutdown worker : 2
I'm working on a pthread system, and i'm trying to implement kind of a pool system.
Currently, i'm creating a pool of 3 workers, then send my jobs with pool->submit().
Then, pool->collect()
And pool->shutdown()
But, i'm disapointed with the result.
Jobs seems to be distributed to all workers evenly
Worker 1 : jobs 1, 4, 7
Worker 2 : jobs 2, 5, 8
Worker 3 : jobs 3, 6, 9
Then, let's say my job 1 is pretty long, and all other are not dat long, my jobs will be finished like so :
2, 5, 3, 6, 8, 9, 1, 4, 7
But, what i'd like to achieve should be more like : 2, 3, 5, 4, 6, 8, 7, 9, 1
Like distributing jobs to the nearest not working worker, so my heavy job is running on worker 1, and all others jobs goes to workers 2 and 3
Is that's something doable ?
I'm i missing something here ?
Code exemple :
<?php
class ChildThread extends Threaded {
public $jobId;
protected $complete;
public function __construct($jobId){
// init some properties
$this->jobId = $jobId;
$this->complete = false;
}
public function run(){
echo "STARTING " . $this->jobId . "\r\n";
//Job ID 1 == heavy waiting
if($this->jobId == 1){
sleep(10);
} else {
sleep(1);
}
echo "ENDING " . $this->jobId . "\r\n";
$this->complete = true;
}
public function isComplete() {
return $this->complete;
}
}
$pool = new Pool(3);
$tasks = array();
// Add tasks to pool queue
for ($i=1; $i<=9; $i++) {
$task = new ChildThread($i);
$pool->submit($task);
$tasks[] = $task;
}
$pool->collect(function($work){
return $work->isComplete();
});
$pool->shutdown();
?>
Result :
STARTING 1
STARTING 2
STARTING 3
ENDING 2
STARTING 5
ENDING 3
STARTING 6
ENDING 5
STARTING 8
ENDING 6
STARTING 9
ENDING 8
ENDING 9
ENDING 1
STARTING 4
ENDING 4
STARTING 7
ENDING 7