Multithreading in PHP - php

I recently read about http://php.net/pcntl and was woundering how good that functions works and if it would be smart to use multithreading in PHP since it isn't a core function of PHP.
I would want to trigger events that don't require feedback through it like fireing a cronjob execution manually.
All of it is supposed to run in a web app written with Zend Framework

The pcntl package works quite fine - it just uses the according unix functions. The only shortage is that you can't use them if php is invoked from a web server context. i.e. you can use it in shell scripts, but not on web pages - at least not without using a hack like calling a forking script with exec or similar.
[edit]
I just found a page explaining why mod_php cannot fork. Basically it's a security issue.
[/edit]

This is not thread control, this is process control. The library for the threads is pthreads (POSIX threads) and it's not included in PHP, so there are no multi-threading functions in PHP.
As of multiprocessing, you cannot use that in mod_php, as that would be a giant security hole (spawned process would have all the web-server's privileges).

The only possible way to have php code executing in multiple threads is to run php as a module of a threaded web server, which is useless because threads are fully isolated and your code has no control over them. As far as i know, pcntl only manages processes, not threads.

If I needed to do manual crontab executions or the like from PHP, I'd probably use a queue. Have a database table that you append jobs to. Another process, either from a cron or running as a daemon, executes the jobs as they show up.
Another way to do it is to set up a separate script and do an HTTP GET to it. It's not quite threading, but it's one way of shelling to another command in PHP.
For example, if I wanted to run /usr/bin/somescript.sh on demand, I'd have a somescript.php that did a system call. This would be on a virtual host only accessible from localhost.
I'd do a socket call to the webserver and GET the script. The key is to not read on the socket so it doesn't block. If I wanted to check the return value of somescript.php, I'd do it later in my main script to prevent blocking.
If somescript.php takes a long time to execute (longer than the calling script), you'll have to do some magic to stop apache from killing the script when the socket is closed.

Multiplatform PHP Multithreading engine
http://anton.vedeshin.com/articles/lightweight-and-multiplatform-php-multithreading-engine

Examples of multithreading working in PHP (with excerpts from their project pages):
Cron Multi-Threaded.
As of October 25th, 2011, this module has reached "end of life" and is deprecated in favor of projects such as Elysia Cron. This module wasn't completely useless in that a core patch inspired by Cron MT was committed to D7.
Boost.
... provides static page caching for Drupal enabling a very significant performance and scalability boost for sites that receive mostly anonymous traffic. For shared hosting this is your best option in terms of improving performance. On dedicated servers, you may want to consider Varnish instead.

Related

Multithread This PHP Script? [duplicate]

I recently read about http://php.net/pcntl and was woundering how good that functions works and if it would be smart to use multithreading in PHP since it isn't a core function of PHP.
I would want to trigger events that don't require feedback through it like fireing a cronjob execution manually.
All of it is supposed to run in a web app written with Zend Framework
The pcntl package works quite fine - it just uses the according unix functions. The only shortage is that you can't use them if php is invoked from a web server context. i.e. you can use it in shell scripts, but not on web pages - at least not without using a hack like calling a forking script with exec or similar.
[edit]
I just found a page explaining why mod_php cannot fork. Basically it's a security issue.
[/edit]
This is not thread control, this is process control. The library for the threads is pthreads (POSIX threads) and it's not included in PHP, so there are no multi-threading functions in PHP.
As of multiprocessing, you cannot use that in mod_php, as that would be a giant security hole (spawned process would have all the web-server's privileges).
The only possible way to have php code executing in multiple threads is to run php as a module of a threaded web server, which is useless because threads are fully isolated and your code has no control over them. As far as i know, pcntl only manages processes, not threads.
If I needed to do manual crontab executions or the like from PHP, I'd probably use a queue. Have a database table that you append jobs to. Another process, either from a cron or running as a daemon, executes the jobs as they show up.
Another way to do it is to set up a separate script and do an HTTP GET to it. It's not quite threading, but it's one way of shelling to another command in PHP.
For example, if I wanted to run /usr/bin/somescript.sh on demand, I'd have a somescript.php that did a system call. This would be on a virtual host only accessible from localhost.
I'd do a socket call to the webserver and GET the script. The key is to not read on the socket so it doesn't block. If I wanted to check the return value of somescript.php, I'd do it later in my main script to prevent blocking.
If somescript.php takes a long time to execute (longer than the calling script), you'll have to do some magic to stop apache from killing the script when the socket is closed.
Multiplatform PHP Multithreading engine
http://anton.vedeshin.com/articles/lightweight-and-multiplatform-php-multithreading-engine
Examples of multithreading working in PHP (with excerpts from their project pages):
Cron Multi-Threaded.
As of October 25th, 2011, this module has reached "end of life" and is deprecated in favor of projects such as Elysia Cron. This module wasn't completely useless in that a core patch inspired by Cron MT was committed to D7.
Boost.
... provides static page caching for Drupal enabling a very significant performance and scalability boost for sites that receive mostly anonymous traffic. For shared hosting this is your best option in terms of improving performance. On dedicated servers, you may want to consider Varnish instead.

Working with Threads using Apache and PHP

Is there anyway to work with threads in PHP via Apache (using a browser) on Linux/Windows?
The mere fact that it is possible to do something, says nothing whatever about whether it is appropriate.
The facts are, that the threading model used by pthreads+PHP is 1:1, that is to say one user thread to one kernel thread.
To deploy this model at the frontend of a web application inside of apache doesn't really make sense; if a front end controller instructs the hardware to create even a small number of threads, for example 8, and 100 clients request the controller at the same time, you will be asking your hardware to execute 800 threads.
pthreads can be deployed inside of apache, but it shouldn't be. What you should do is attempt to isolate those parts of your application that require what threading provides and communicate with the isolated multi-threading subsystem via some sane form of RPC.
I wrote pthreads, please listen.
Highly discouraged.
The pcntl_fork function, if allowed at all in your setup, will fork the Apache worker itself, rather than the script, and most likely you won't be able to claim the child process after it's finished.
This leads to many zombie Apache processes.
I recommend using a background worker pool, properly running as a daemon/service or at least properly detached from a launching console (using screen for example), and your synchronous PHP/Apache script would push job requests to this pool, using a socket.
Does it help?
[Edit] I would have offered the above as a commment, but I did not have enough reputation to do so (I find it weird btw, to not be able to comment because you're too junior).
[Edit2] pthread seems a valid solution! (which I have not tried so I can't advise)
The idea of "thread safe" can be very broad. However PHP is on the very, furthest end of the spectrum. Yes, PHP is threadsafe, but the driving motivation and design goals focus on keeping the PHP VM safe to operate in threaded server environments, not providing thread safe features to PHP userspace. A huge amount of sites use PHP, one request at a time. Many of these sites change very slowly - for example statistics say more sites serve pages without Javascript still than sites that use Node.js on the server. A lot of us geeks like the idea of threads in PHP, but the consumers don't really care. Even with multiple packages that have proved it's entirely possible, it will likely be a long time before anything but very experimental threads exist in PHP.
Each of these examples (pthreads, pht, and now parallel) worked awesome and actually did what they were designed to do - as long as you use very vanilla PHP. Once you start using more dynamic features, and practically any other extensions, you find that PHP has a long way to go.

Why is pcntl_fork() disabled in PHP?

I was trying to setup a multi-threaded socket application, but whenever I ran it I got an error because pcntl_fork() was disabled by default. Is this because it is dangerous or unstable? Should I look for some other way to multithread, or is it just disabled because it is not often used?
pcntl_fork() is not for multithreading, it only... well, forks the current proccess. Be sure to check the documentation for more information on the function.
The best reason I can think of it's disable by default, it's because PHP was never meant for parallel computing, it's merely a scripting language (a very powerful one at that). As Martin suggestted on his answer in a similar question, you're better off running a CRON or another program.
It simply is a function that should not be used in the average shared-hosting apache environment. Forking there would possibly clone a rather big process and besides that the function can be abused to bring down a poorly configured server (fork bomb).
Using it e.g. in a commandline based PHP script is perfectly fine.

Daemonizing a PHP script without pcntl_fork()

I'm working on an embedded system that is programmed with PHP 4.4.9 - unfortunately without the PCNTL extension.
I need to create a script that runs in the background as a daemon. You'd usually do this using fork(), or in the PHP case, pcntl_fork() - but this function is not available. A shell is also missing, so I can't use the standard tools.
So, what other ways are there to cleanly start a process in the background?
As kingCrunch says, you really should upgrade.
Firstly, there's more to making a daemon than just calling pcntl_fork(). You might want to read the Unix programming FAQ and the Unix socket FAQ.
Next, you've not mentioned how you intend to solve the problem of concurrency - while forking is one solution to this it is not the only reason for using fork() in a daemon.
So you've really got 2 problems to solve, first how you daemonize the program then how you handle concurrency.
Note that one approach to the latter which obviates the former is to run the server from [x]inetd.
Another approach to solving the concurrency problem is to run a single threaded server and use socket_select (or stream_select) to multiplex the connections - but I'm not sure how well that is supported in PHP 4 - there is a good example here.
A simple solution would be to write a simple wrapper program in C using daemon() to bootstrap the program. Or you could start it up directly from inittab. Or for a solution with complex management facilities have a look at DJB's daemontools

Does PHP support asynchronous programming?

I'm new to PHP. I am familiar with ASP.NET which support asynchronous programming. That is, if one request needs to do some I/O job. It is suggested to program the web page with BeginProcess/EndProcess way. The asynchronous programming is key to improve scalability.
I'm wondering whether there is counterpart of asynchronous programming(BeginXXXX/EndXXXX) in PHP world.
In .NET BeginXXX/EndXXX paradigm relies heavily on threading, while on PHP I am not sure that you could even start a new thread (except maybe the PECL package).
FastCGI is the alternative to multithreading in most interpreted languages. Instead of spawning new threads it uses processes, but as spawning a new process is expensive, it keeps a reusable process pool just as the ThreadPool in .NET.
If the I/O is performed with sockets or files you should use stream_socket_select() or stream_select() respectively (similar to system calls in C/C++).
Here's a simple command line chat tutorial done with PHP:
Simple PHP socket-based terminal chat
Note: This is not a general multi-threading solution, but a simple solution for situations where you need "semi-parallel" I/O
The core has a set of process control functions, including the ability to fork a process.
I don't know that I'd use these in a web script, but have used them in command line scripts before.
http://www.php.net/manual/en/book.pcntl.php
http://www.php.net/manual/en/pcntl.example.php
Here's an interesting link on the subject of PHP multiplexing with PHP4 and PHP5 samples:
http://netevil.org/blog/2005/may/guru-multiplexing
PHP doesn't, but you could use AJAX once the page has loaded, which will allow asynchronous requests.
Honestly though, there is no point. If you really want that heavyweight of a back end, you're better off writing a separate program that does the heavy lifting. PHP modules are written in pure C as far as I'm aware, so you should be able to use that and then call your own custom function from PHP.
Using stream_select you can create child processes via a HTTP request. Checkout the code in http://drupal.org/project/httprl for some ideas on how to do this. I plan on pushing this library to github once I get it more polished; something that can be ran outside of drupal. But for now it lives in Drupal land.

Categories