php实现非阻塞
实现非阻塞的常见方法
在PHP中实现非阻塞操作通常用于提高性能或处理并发任务。以下是几种常见方法:
使用pcntl_fork创建子进程
通过fork创建子进程可以让主进程继续执行而不等待子进程完成:
$pid = pcntl_fork();
if ($pid == -1) {
die('Could not fork');
} elseif ($pid) {
// 父进程
pcntl_wait($status); // 非必须,如果不等待就是非阻塞
} else {
// 子进程
sleep(5); // 模拟耗时操作
exit;
}
使用popen执行后台命令
popen可以异步执行系统命令:
$handle = popen('/path/to/long_running_script.php > /dev/null &', 'r');
pclose($handle); // 立即返回
使用curl_multi实现并发HTTP请求
处理多个HTTP请求时可以使用curl_multi:
$mh = curl_multi_init();
$handles = [];
for ($i = 0; $i < 5; $i++) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://example.com/?q=$i");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_multi_add_handle($mh, $ch);
$handles[] = $ch;
}
do {
curl_multi_exec($mh, $running);
curl_multi_select($mh);
} while ($running > 0);
foreach ($handles as $ch) {
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
使用消息队列
通过消息队列解耦处理过程:
// 生产者
$queue = msg_get_queue(12345);
msg_send($queue, 1, 'data_to_process', true, false);
// 消费者(可单独运行)
$queue = msg_get_queue(12345);
msg_receive($queue, 0, $msgtype, 1024, $message, true, MSG_IPC_NOWAIT);
使用Gearman等任务队列系统
Gearman提供了分布式任务处理能力:
$client = new GearmanClient();
$client->addServer();
$client->doBackground('process_data', 'payload'); // 非阻塞调用
使用PHP的异步扩展
如Swoole等异步框架:

$http = new Swoole\Http\Server("0.0.0.0", 9501);
$http->on('request', function ($request, $response) {
$response->end("Hello World");
});
$http->start();
注意事项
- 非阻塞操作需要考虑资源竞争和同步问题
- 长时间运行的任务需要妥善处理超时和错误
- 生产环境建议使用专门的队列服务如RabbitMQ
- 注意PHP的max_execution_time限制






