The following are my findings, I cannot provide you any reference to documentation to prove my statements. However, I learned the way the PHP interpreter handles the ticks and the signals by reading the PHP's source code (the pcntl
extension).
- If we set
ticks = 5
, does that mean we have a 4 in 5 chance the signal handler won't be called at all?
PHP is an interpreted language. Your PHP signal handlers are not called by the OS to handle the signals. The interpreter registers a signal handler with the OS and puts all the signals it receives into a queue.
The OS signals come asynchronous. The interpreter dispatches the signals to the handlers defined by you when it's the most appropriate time for it. This happens between the low-level tickable statements.
declare(ticks = 5);
makes the signals dispatcher run once every 5 tickable statements. The signals that arrive during two calls to the dispatcher are not lost; they are added to the queue and processed on the next call.
The code of the signals dispatcher is pretty light; it is not a big overhead to use declare(ticks = 1)
.
- How can I determine a consistent but efficient setting?
It depends on what your program does. There is no recipe for that. Try different settings, pick the one that suits you best.
- What happens during blocking calls, like database queries? Is the signal thrown away or processed when it returns?
As I said above, the signals come and are processed asynchronously by the signal handler installed by the interpreter. The handling only puts the signals in the queue. They are picked from the queue and dispatched to your code when it's the most appropriate moment for the interpreter (and your PHP code too). Nothing is lost.
Regarding the database, I only checked (some years ago) with mysql
. My code was using pcntl_fork()
to create worker processes and was processing SIGCHLD
to keep track of workers activity. For mysterious reasons it was failing on the MySQL queries frequently with the message "connection lost" without any apparent reason. After extensive investigation and reading of a lot of documentation, I found out that the signals make the functions from the sleep()
family return early and that makes the code of the mysql
client library think the connection was lost.
The solution was very simple. I used pcntl_sigprocmask()
to block the SIGCHLD
signal before running a MySQL query and unblock it immediately after the query completes. I was not interested in other signals. Letting them come would lead to process termination; why bothering about a failed MySQL query when the program was about to exit anyway?
I don't know if the signals affect the operation of mysqli
or PDO
but I think they do. The operation that was affected in my case was part of the low-level communication between the MySQL client and server, deep down in the libmysql
and not in the PHP extension.
In your case, you probably need to block SIGHUP
(this is the signal that is usually sent to the daemons to make them re-load their configuration).