RE: [PHP] semaphores are broken
| From: | Jeremy Greene | Date: | Sun, 08 May 2011 21:54:50 +0000 |
| Subject: | RE: [PHP] semaphores are broken | ||
| References: | 1 2 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-312728@lists.php.net to get a copy of this message | ||
This is on a simple-ish embedded system. And yes, I did see the code --
that's when I kind of choked :) And, yes, I did implement the interrupt
handler, but liked the design that it would just set a sem that the main
loop can wait for. But that means that the main loop is waiting on a sem
that will get and EINTR now and then. So there's the problem.
I have switched to the approach of putting code in the interrupt
handler... which I guess is fine. It's just annoying that I wasted time
with the 1st approach, that I think is a very reasonable design. And, I
have always been hesitant to put much code in an interrupt handler -- I
have always thought that has issues too.
Jeremy
-----Original Message-----
From: Rasmus Lerdorf [mailto:rasmus@lerdorf.com]
Sent: Sunday, May 08, 2011 11:38 AM
To: Jeremy Greene
Cc: php-general@lists.php.net
Subject: Re: [PHP] semaphores are broken
On Fri, May 6, 2011 at 12:57 PM, Jeremy Greene <jeremy@zeevee.com>
wrote:
> Then.... I find out that sem_acquire() actually returns **OK** when
the
> underlying semop call gets an EINTR!!! Holy cow. How can a "php
system"
> call loose an error?! That's just crazy.
Generally you don't care about an EINTR on a semop() call. If you do
you will have installed a signal handler to handle that interruption.
The low-level code has:
while (semop(sem_ptr->semid, &sop, 1) == -1) {
if (errno != EINTR) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to %s
key 0x%x: %s", acquire ? "acquire" : "release", sem_ptr->key,
strerror(errno));
RETURN_FALSE;
}
}
which ignores the EINTR as you can see. If you really want to get in
there to handle the uncaught interruption you can do:
pcntl_signal(SIGEINTR, function($signo) {
echo "Interrupted\n";
});
sem_acquire(...);
pcntl_signal_dispatch();
But in general, using semaphores in a Web app is a bad idea. Any sort
of locking is bound to get you in trouble which is also why PHP resets
the semaphore at the end of a request.
Generally you will want to think beyond a single server and look at a
message passing mechanism to communicate between a PHP app and a
server process. I think my favourite way to implement this today is
through ZeroMQ. There is a good guide to it at:
http://zguide.zeromq.org/page:all
http://www.zeromq.org/bindings:php
Or if you want something higher level you could have a look at
Gearman. Your server could register itself as a Gearman worker and you
could use the nice Gearman API to communicate with the server.
-Rasmus