-
-
Notifications
You must be signed in to change notification settings - Fork 156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EventBase::loop(): kevent: Bad file descriptor #280
Comments
@clue @WyriHaximus Can anyone pay attention to this issue, tks |
@slince We can expose the raw event base, but why not start the server after forking. Or use |
hello
If so, then we need to enable the
In fact, i have an idea. i can create an socket server importing an existing socket stream . before this, i have a discusssion #220 // create raw socket befor fork.
$rawSocket = stream_socket_server('xxxx');
const WORKER_NUM = 3;
for ($i = 0; $i <= WORKER_NUM; $i++) {
$pid = pcntl_fork();
if (-1 === $pid) {
exit('fork error');
} elseif ($pid) {
} else {
// create a server using raw socket
$loop = \React\EventLoop\Loop::get();
$server = new \React\Socket\SocketServer($rawSocket, $loop);
$loop->run();
exit;
}
}
pcntl_wait($status); |
@slince Thanks for bringing this up, excellent question! Whether PHP's The underlying problem is that libev and others rely on epoll/kevent which use a file descriptor which will be inherited to any child processes when forking the parent. As a consequence, any child process may affect events received by the parent process and vice versa. The underlying libev and others implement low-level APIs to essentially re-create this file descriptor in the child process, which is not currently exposed in our EventLoop API because it is somewhat specific to the platform and/or extension in use. For more background, see the above ticket and https://metacpan.org/dist/EV/view/libev/ev.pod#The-special-problem-of-fork I believe this has been answered, so I'm closing this for now. Please come back with more details if this problem persists and we can always reopen this 👍 |
@clue hi I think fork is worthy using, you can refer to workerman, it has been working very well and has been trusted by everyone; |
@slince Forking works just fine, also in ReactPHP. Like I said, using the If you really want to use the low-level forking functions in PHP to create a shared file descriptor referencing a socket server, here's how you can do this: <?php
require __DIR__ . '/vendor/autoload.php';
// create raw socket befor fork.
$rawSocketFd = 3; // TODO: low-level stuff not exposed in PHP, but safe to assume in here if you don't have any other file descriptors except stdio
$rawSocket = stream_socket_server('xxxx');
const WORKER_NUM = 3;
for ($i = 0; $i <= WORKER_NUM; $i++) {
$pid = pcntl_fork();
if (-1 === $pid) {
exit('fork error');
} elseif ($pid) {
} else {
// create a server using raw socket
$loop = \React\EventLoop\Loop::get();
$server = new \React\Socket\SocketServer('php://fd/' . $rawSocketFd, $loop);
$loop->run();
exit;
}
}
pcntl_wait($status); The above example should work just fine with ReactPHP, but again I would not recommend using this unless you have a very good understanding of how lower-level file descriptors work. In particular, you may find that PHP does not expose file descriptor numbers at all, does not allow you to get a FD number for a resource or even I hope this helps 👍 |
hello,
I'm writing forking TCP server with master and forked worker processes. the
ExtEventLoop
instance in child process will raise some error like this:Sample code:
environment:
Reference https://stackoverflow.com/questions/33735302/reactphp-libevent-and-socket-pair-throws-error
Is it possible to add a method
getEventBase()
in https://github.com/reactphp/event-loop/blob/master/src/ExtEventLoop.php to expose the raweventBase
object?The text was updated successfully, but these errors were encountered: