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
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.
Guys recently I decided to go back to PHP and do some more complex stuff than a simple log in page. For 3 years I've been programming with Java/JavaEE and have a good understanding of the architecture of of Java Applications. Basically, a virtual machine ( a simple OS process ) that runs compiled code called byte code. a simple Java web server is basically a java application that listens on provided TCP port for Http requests and responds accordingly of course it is more complicated than that but this is its initial work.
Now, what about PHP ? How does it work ? What, in a nutshell, is its architecture.
I googled about this question but in 90% the articles explain how to implement and construct a web application with PHP which is not what I am looking for.
The biggest difference between a Java web server and PHP is that PHP doesn't have its own built-in web server. (Well, newer versions do, but it's supposed to be for testing only, it's not a production ready web server.) PHP itself is basically one executable which reads in a source code file of PHP code and interprets/executes the commands written in that file. That's it. That's PHP's architecture in a nutshell.
That executable supports a default API which the userland PHP code can call, and it's possible to add extensions to provide more APIs. Those extensions are typically written in C and compiled together with the PHP executable at install time. Some extensions can only be added by recompiling PHP with additional flags, others can be compiled against a PHP install and activated via a configuration file after the fact. PHP offers the PEAR and PECL side projects as an effort to standardise and ease such after-the-fact installs. Userland PHP code will often also include additional third party libraries simply written in PHP code. The advantage of C extensions is their execution speed and low-level system access, the advantage of userland code libraries is their trivial inclusion. If you're administering your own PHP install, it's often simple enough to add new PHP extensions; however on the very popular shared-host model there's often a tension between what the host wants to install and what the developer needs.
In practice a web service written in PHP runs on a third party web server, very often Apache, which handles any incoming requests and invokes the PHP interpreter with the given requested PHP source code file as argument, then delivers any output of that process back to the HTTP client. This also means there's no persistent PHP process running at all times with a persistent state, like Java typically does, but each request is handled by starting up and then tearing down a new PHP instance.
While Java simply saves persistent data in memory, data persistence between requests in PHP is handled via a number of methods like memcache, sessions, databases, files etc.; depending on the specific needs of the situation. PHP does have opcode cache addons, which kind of work like Java byte code, simply so PHP doesn't have to repeat the same parse and compile process every single time it's executing the same file.
Do keep in mind that it's entirely feasible to write a persistent PHP program which keeps running just like Java, it's simply not PHP's default modus operandi. Personally I'm quite a fan of writing workers for specific tasks on Gearman or ZMQ which run persistently, and have some ephemeral scripts running on the web server as "frontend" which delegate work to those workers as needed.
If this sounds like a typical PHP app is much more of a glued-together accumulation of several disparate components, you'd be correct. Java is pretty self-contained, except for external products like RDBMS servers. PHP on the other hand often tends to rely on a bunch of third party products; which can work to its advantage in the sense that you can use best-of-breed products for specific tasks, but also requires more overhead of dealing with different systems.
This is how does PHP work:
(one of the best over the Internet)
In general terms, PHP as an engine interprets the content of PHP files (typically *.php, although alternative extensions are used occasionally) into an abstract syntax tree. The PHP engine then processes the translated AST and then returns the result given whatever inputs and processing are required.
Below image will depict more information
Source: freecodecamp.org
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.
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
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.