views:

474

answers:

8

Hi all,

I am trying to create a multi threaded PHP application right now. I have read lots of paper that explains how to create multi threading. All of those examples are built on diving the processes on different worker PHP files. Actualy that is also what I am trying to do but there is a problem :)

There are too many jobs even to divide in 30 seconds (which is the execution time limit)

We are using multi server environment on local network to complete the processes as the processes do not linked to each other or shares the same memory. We just need to fire them up and let them work at an exact time. Each of the processes works for 0.5 secs but it has a possibility to work for 30 secs.

Most of the examples fires up the PHP's and waits for the results. But unfortunately in my situation I dont need to expect a result from the thread. I just need it to execute the command and write the result to its own database.

How can I achieve to fire up the phps and wait for them to work for 10000 processes ?

ADDITIONAL INFO: I know that PHP neither have multi threading feature nor is built for. But we have to create a way to use it for instance we can send request to http://server1/dothis.php?jobid=5 but standart methods makes us wait for the result. If we can manage to send request to this server without waiting for result it would solve our problem I think or we will need completely different approach such as a process divider with c++ or qt.

+2  A: 

Since PHP does not have the ability to support multithreading, I don't quite know how to advise you. Each time a new script is loaded, a new instance of PHP is loaded, so if your server can handle X many PHP instances, then you can do what you want.

Here is something however:

Code for background execution

 <?php 
function execInBackground($cmd) { 
    if (substr(php_uname(), 0, 7) == "Windows"){ 
        pclose(popen("start /B ". $cmd, "r"));  
    } 
    else { 
        exec($cmd . " > /dev/null &");   
    } 
} 
?> 

Found at http://php.net/manual/en/function.exec.php#86329

Laykes
This may be a solution to our problem but if popen is attached to process and waits for it to complete its job then process opener script passes the execution time limit and other processes that are in the queue does not start.
Harun Baris Bulut
+3  A: 

As the comments say, multi-threading is not possible in PHP. But based on your comment:

If we can manage to send request to this server without waiting for result it would solve our problem I think

You can start a PHP script to run in the background using exec(), redirecting the script's output somewhere else (e.g. /dev/null). I think that's the best you will get. From the manual:

Note: If a program is started with this function, in order for it to continue running in the background, the output of the program must be redirected to a file or another output stream. Failing to do so will cause PHP to hang until the execution of the program ends.

There are several notes and pointers in the User Contributed Comments, for example this snippet that allows background execution on both Windows and Linux platforms.

Of course, that PHP script will not share the state, or any data, of the PHP script you are running. You will have to initialize the background script as if you are making a completely new request.

Pekka
So if script lets say a.php runs exec('... b.php > .../log1.txt', ...); and b.php does the execution for 20 seconds and a.php ends in 1 secs. Does b.php still working on the execution or a.php wait for b ? If it waits for b how can it execute another worker like c.php in the mean time ?
Harun Baris Bulut
@Harun a.php won't wait for b.php. a.php can execute as many workers as it wants by repeating the exec() procedure.
Pekka
@Pekka thanks again Pekka, I will also try build my solution on to this.
Harun Baris Bulut
+2  A: 

Do you really want to have multi-threading in php?

OR do you just want to execute a php script every second? For the latter case, a cronjob-like "execute this file every second" approach via linux console tools should be enough.

Karsten
The main php file is triggered by a cron of course but other php scripts that are located on various node servers so the main server should tell them to start execution. node servers should not start execution before the main server tell them to.
Harun Baris Bulut
+1  A: 

If your task is to make a lot of HTTP requests you can use curl multi. There is a good library for doing it: http://code.google.com/p/rolling-curl/

Sam Dark
I have looked at CURL multi but some says there occur a really big overhead when it is used for large amount of urls. In addition to that we dont need to see the result. If execution passes the execution time limit it is also a information for us that execution could not end succesfully.
Harun Baris Bulut
+2  A: 

As everyone's already mentioned, PHP doesn't natively support multi-threading and the workarounds are, well, workarounds...

That said, have you heard of the Facebook PHP Compiler? Basically it compiles your PHP to highly optimized C++ and uses g++ to compile it. This opens up a world of opportunities, including but not limited to multi-threading!

The project is open-source and its on github

Alex
I know this one this is a fantastic job which I was looking ages :) But as we think from the side of our developers, it would be very hard to explain this to them in this situation but thanks again, we will be looking for this as an alternative :)
Harun Baris Bulut
+3  A: 

i think this http://gearman.org/ can help you

tomaszsobczak
I am looking for it thank you.
Harun Baris Bulut
Got there first, nice one tomas ;)
danp
A: 

if you just want to post a HTTP request, just do it using PHP CURL lib. It will solve your issue.

coder
+2  A: 

As has been pointed out, php doesn't support multi threading. However, and as tomaszsobczak mentioned, there is a library which will let you create "threads" and leave them running, and reconnect to them through other scripts to check their status and so on, called "Gearman".

From the project homepage: "Gearman provides a generic application framework to farm out work to other machines or processes that are better suited to do the work. It allows you to do work in parallel, to load balance processing, and to call functions between languages. It can be used in a variety of applications, from high-availability web sites to the transport of database replication events. In other words, it is the nervous system for how distributed processing communicates."

Rasmus' blog has a great write up about it here: playing with gearman and for your case, it might just be the solution, although I've not read any in depth test cases... Would be interested to know though, so if you end up using this, please report back!

danp
This will be the solution I think thank you both tomaszsobczak ant danp :)
Harun Baris Bulut