PHP中的并发性

9
我目前在开发使用PHP作为服务器端API时,需要频繁地进行MySQL查询,我希望通过多线程执行不同的查询并返回结果来加速它。
但是如何在PHP中创建另一个线程呢?由于我正在传递POST参数,因此简单的shell_exec()可能有效,但似乎有些不安全。以下是我正在考虑的选项:
1)使用现有参数进行cURL请求,处理请求中的JSON,然后返回结果;
2)使用PHP CLI调用shell_exec(),然后以某种方式(具体应该怎么做?)在PHP中处理响应。
请问这里有什么最佳方案吗?

通常使用队列和工作器来完成,它会监控它。 - zerkms
你设置一些队列管理软件(例如rabbitmq),然后你的脚本将任务添加到队列中,一些后台工作程序会执行它。 - zerkms
2
与其走这条复杂的路线,不妨去探索优化和缓存等替代方案。如果您的瓶颈确实是在等待一个无法进一步加速或缓存的查询,并且您认为并行执行更多的查询实际上会有所帮助,那么从同一个脚本建立多个连接,使用非阻塞的API发起查询,然后在之后获取结果可能会更容易。 - deceze
几个连接?用PHP编写的非阻塞API?我不确定你具体是在说什么——我的意思是,我想异步地进行调用并返回它们,我的问题是如何做到这一点。 - lollercoaster
http://gonzalo123.wordpress.com/2010/10/11/speed-up-php-scripts-with-asynchronous-database-queries/ - aziz punjani
3个回答

4
PHP没有线程支持。不过,你可以使用 pcntl 扩展来创建和管理子进程,但如果你认为必须使用线程完成任务,最好再仔细考虑一下你的算法。
一个处理长时间操作异步化的选择是将它们存储在数据库中,并让后台工作进程从数据库中获取它们、计算结果,然后将结果存储在数据库中。接着,前端脚本会在数据库中查找这些结果,以确定它们是否已经完成以及结果是什么。

1
如果是这样,大型网站是如何使用PHP构建的? - lollercoaster
1
在我看来,对于性能关键的API/具有许多数据库交互的网站,需要并发处理。 - lollercoaster
@lollercoaster:存储并发与 PHP 并发无关。存储自己处理它们。 - zerkms
1
@lollercoaster,大多数繁重的任务可以通过后台处理和缓存的组合来完成。 - rid

3

看看pcntl扩展。PHP并不支持真正的线程,所以你需要通过fork()来实现伪线程。请注意,fork()一个进程比生成一个线程更加“沉重”。


2
PHP没有实现线程(可能永远都不会),因为许多PHP库是不支持多线程的。可以采用的替代方案是“pcntl”,它包装了C语言的“fork”函数。
我已经创建了一个方便的封装器来更高级地管理这些函数。
$thread1 = new Thread( function( $thread ) {
    sleep( 4 );
    $thread->write( "Hello\n" );
} );

$thread2 = new Thread( function( $thread ) {
    sleep( 5 );
    $thread->write( "World\n" );
} );

$thread3 = new Thread( function( $thread ) {
    sleep( 6 );
} );

print $thread1->read(); // time: 0 -> 4
print $thread2->read(); // time: 4 -> 5
$thread3->join(); // time 5 -> 6

// More advanced handling:
// Thread::selectUntilJoin( array( $thread1, $thread2, $thread3 ), function () { ... }, function () { ... } );

意思是这些函数不能从不同的线程调用,这并不是 TS 代码的正确定义。 - zerkms

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接