Get return value from php threads - php

This is the sample code, I'm working on
class workerThread extends Thread {
public function __construct($i){
$this->i=$i;
}
public function run(){
while(true){
echo $this->i;
sleep(1);
}
}
}
for($i=0;$i<50;$i++){
$workers[$i]=new workerThread($i);
$workers[$i]->start();
}
What is the appropriate way to get return value from run() or should create another function for callback?

well first you have to wait for all threads to finish.
so after your initial loop you should do one more loop waiting for each worker to finish. there is thread->join function that syncs your main thread with the sub-thread. causing to halt the execution and wait until the sub thread finishes. so if you call if($worker->join()) {...} you can be sure, that the worker is done working :)
http://php.net/manual/de/thread.join.php
second, a thread does not return a value. instead create a variable in your class, for example result and fill it with data during the run of a thread. collect at the end (after join) the $worker->result
third, your current threads even cannot report any result, as they run for ever. From the question I dont understand, if you want them to run for ever? Because if you do there are more complicated steps involved to get the results continuously.

Related

PHP 5.6 signal handling: declare(ticks=1) vs pcntl_signal_dispatch()

I'm writing a daemon in PHP 5.6. So far, it is basically a Daemon class with a mainLoop() method that has an infinite loop. In each iteration, the mainLoop executes a series of steps.
I need it to implement a "graceful kill" mechanism: if a SIGINT or SIGTERM arrive, the daemon must complete the current step of the current iteration before dying.
My idea is to use a static variable Daemon::CONTINUE TRUE by default; when a SIGINT or SIGTERM arrives, it is set to FALSE.
In each iteration, before passing to the next step the daemon checks if self::CONTINUE has switched to FALSE and, if it has, it returns.
I know that the way to do this is to use pcntl_signal. It seems that I can either use it with declare(ticks=1) or with pcntl_signal_dispatch(), but I'm not sure about the difference.
Does declare(ticks=1) make the process check for the arrival of signals after each tick, whereas pcntl_signal_dispatch() explicitly checks the signals only when I call it?
These are snippets of the two ways I described before. Are they both correct? Which one should I use?
Way 1
<?php
declare(ticks=1) {
pcntl_signal(SIGINT, function($signo) {Daemon::CONTINUE = FALSE;});
pcntl_signal(SIGTERM, function($signo) {Daemon::CONTINUE = FALSE;});
}
public class Daemon {
public static $CONTINUE = TRUE;
function mainLoop() {
...
if (self::CONTINUE === FALSE)
return;
...
}
}
Way 2
<?php
pcntl_signal(SIGINT, function($signo) {Daemon::CONTINUE = FALSE;});
pcntl_signal(SIGTERM, function($signo) {Daemon::CONTINUE = FALSE;});
public class Daemon {
public static $CONTINUE = TRUE;
function mainLoop() {
...
pcntl_signal_dispatch();
if (self::CONTINUE === FALSE)
return;
...
}
}
Thanks for your support.
Ok, after some testing and debugging I tried both solutions.
I'll leave here my observations in case somebody encounters my same issues.
It seems that the way 1 with declare(ticks=1) does not work; I can not understand why.
The way 2 with pcntl_signal_dispatch(), on the contrary, seems to work nice.
After deeper research, I think that the way 2 is the best one for my case anyway.
In fact, declare(tick=1), if it worked, would run the pcntl_signal on each tick, roughly corresponding to the execution of each code line.
This can potentially degradate the performances.
On the contrary, apparently pcntl_signal_dispatch) just handles pending signals when it is called, so it should be lighter on performances.

How to use threading in Laravel to run stored procedures

I want to use php threads for asynchronously loading a function that executes a mysql stored procedure. The stored procedure takes a lot of time to load, so keeping it asynchronous is the only optimal solution, I found.
I have no idea on how to bring the threading inside Laravel. Laravel has queues but I want to do it directly in script with thread.
What i've done to approach a similar issue (I've done it in a sync command) is to create a class that extends from Thread and call it from the laravel code.
The class in your case might be something like this:
class LaravelWorker extends Thread
{
private $object;
public function __construct($object)
{
$this->object = $object;
}
public function run()
{
$object->runProcedure();
}
}
And you can call it at your code such as this:
$object = new ObjectWithProcedure();
$threadedMethod = new LaravelWorker($object);
$threadedMethod->start();
If, for some reason, you need to wait until the $threadedMethod finishes, you can do
$threadedMethod->join();
(more_code...)
And the more_code section will only execute once $threadedMethod has ended.
Hope it helps!

PHP thread do not end

I tried to implement multithreading in php to fetch data from a data source parallely.
But in the process, the threads i create to fetch the data continue to remain in the memory, even after the fetching.
This is the class that i call
class ClassName extends Thread {
public function __construct($i){
$this->i=$i;
}
public function run(){
// functionCallToDataSource($this->i);
}
}
and i call this class here (in a loop).
$workers = new ClassName(parameter);
$workers->start();
$workers->kill(); //this isnt working
This kill() doesnt seem to work for me, as the memory is not reduced after the functions have been performed.
I have to restart my server to free the blocked memory

for each loop calls a heavy function. Does the loop call the function before it is complete

I have a loop that calls a function that produces documents, a crap ton of variables and several emails. The loop will go through about 10-20 iterations on average and I am wondering if it calls the functions simultaneously or if it waits until the function is complete before it calls it again.
foreach ($campaign as $key=>$val){
produce_docs($val['id']);
}
function produce_docs(campaign_id){
//Big function
//does not return anything
}
it will wait until the function is complete before calling it again.

PHP - Troubles using pcntl_fork with shutdown function

I had some several scripts that were running for a long time (6+ hours).
They were all containing a main loop that did it's thing, and a registered shutdown function that triggered a mysql query to announce the process as "done".
I decided to use pcntl_fork() inside these main loops, to run each round as a different process, in order to make the entire script complete faster.
It works OK, but, each child process is still registered with the shutdown function.
Therefore, each time a child process is complete it calls that mysql query and announce the script as complete.
How can I disable that shutdown function for the child processes, but keep it alive for the parent?
Sample code to understand what's going on:
common.php
register_shutdown_function('shutdown');
function shutdown()
{ global $objDb,$arg_id ;
echo "\n\n Executing queue process shutdown function.";
$objDb->query("UPDATE queue_args SET done='1' WHERE id='{$arg_id}'");
}
loop.php
include('common.php');
for ($i=1;$i<=200;$i++){
$pid = pcntl_fork();
if (!$pid) {
//child proccess - do something without calling the shutdown function
posix_kill(getmypid(),9);
}
} exit(); //this is when the shutdown function should eventually be called
Thanks
You could register the shutdown function within the if, like this:
if ($pid) {
if(!$registered) {
$registered = true;
register_shutdown_function('shutdown');
}
}else{
//child proccess - do something without calling the shutdown function
posix_kill(getmypid(),9);
}
You can't.
You could set a flag in the child processes after forking and poll it in the shutdown function - if it's set then return early. Or store the parent pid before you fork and, inside the shutdown function, return early if that's not the current pid. Or register the function in the parent process after forking.
if (!$pid) { posix_kill(getmypid(),9); }
This is really bad way to prevent the shutdown function from being invoked in the child process - but has all sorts of other implications - PHP won't shut down cleanly, buffers won't be flushed. Maybe you just need to do this:
#!/usr/bin/php
<?php
$arg_id = exec('task_which_forks.php');
exec("queue_clean_up.php $arg_id");

Categories