✨ New Feature:
Swoolesupports multi-threading mode. WhenPHPis inZTSmode andSwooleis compiled with--enable-swoole-thread, the multi-threading mode can be utilized.- Added a new thread management class
Swoole\Thread. @matyhtf - Introduced thread lock
Swoole\Thread\Lock. @matyhtf - Added thread atomic counter
Swoole\Thread\Atomic,Swoole\Thread\Atomic\Long. @matyhtf - Added safe concurrent containers
Swoole\Thread\Map,Swoole\Thread\ArrayList,Swoole\Thread\Queue. @matyhtf - File asynchronous operations support
iouringas the underlying engine. Installingliburingand compilingSwoolewith--enable-iouringenables asynchronous operations for functions likefile_get_contents,file_put_contents,fopen,fclose,fread,fwrite,mkdir,unlink,fsync,fdatasync,rename,fstat,lstat,filesizethroughiouring. @matyhtf @NathanFreeman - Upgraded
Boost Contextto version 1.84. Now, Loongson CPUs can also support coroutines. @NathanFreeman
📖 example:
- How to create threads
use Swoole\Thread;
$args = Thread::getArguments(); // If it is main thread, the $args is empty; if it is a child thread, the $args is not empty.
$c = 4;
if (empty($args)) {
# main thread
for ($i = 0; $i < $c; $i++) {
$threads[] = new Thread(__FILE__, $i);
}
for ($i = 0; $i < $c; $i++) {
$threads[$i]->join();
}
} else {
# child thread x 4
echo "Thread #" . $args[0] . "\n";
while (1) {
sleep(1);
file_get_contents('https://www.baidu.com/');
}
}- Thread + Server (Asynchronous Style)
use Swoole\Process;
use Swoole\Thread;
use Swoole\Http\Server;
$http = new Server("0.0.0.0", 9503, SWOOLE_THREAD);
$http->set([
'worker_num' => 2,
'task_worker_num' => 3,
'bootstrap' => __FILE__,
// sharing data between threads through `init_arguments`.
'init_arguments' => function () use ($http) {
$map = new Swoole\Thread\Map;
return [$map];
}
]);
$http->on('Request', function ($req, $resp) use ($http) {
$resp->end('hello world');
});
$http->on('pipeMessage', function ($http, $srcWorkerId, $msg) {
echo "[worker#" . $http->getWorkerId() . "]\treceived pipe message[$msg] from " . $srcWorkerId . "\n";
});
$http->addProcess(new Process(function () {
echo "user process, id=" . Thread::getId();
sleep(2000);
}));
$http->on('Task', function ($server, $taskId, $srcWorkerId, $data) {
var_dump($taskId, $srcWorkerId, $data);
return ['result' => uniqid()];
});
$http->on('Finish', function ($server, $taskId, $data) {
var_dump($taskId, $data);
});
$http->on('WorkerStart', function ($serv, $wid) {
// Retrieve shared data passed by `init_arguments` in the configuration using `Swoole\Thread::getArguments()`.
var_dump(Thread::getArguments(), $wid);
});
$http->on('WorkerStop', function ($serv, $wid) {
var_dump('stop: T' . Thread::getId());
});
$http->start();- Thread + Coroutine
use Swoole\Thread;
$args = Thread::getArguments(); // If it is main thread, the $args is empty; if it is a child thread, the $args is not empty.
$c = 4;
if (empty($args)) {
# main thread
for ($i = 0; $i < $c; $i++) {
$threads[] = new Thread(__FILE__, $i);
}
for ($i = 0; $i < $c; $i++) {
$threads[$i]->join();
}
} else {
# child thread x 4
echo "Thread #" . $args[0] . "\n";
Co\run(function() {
while (1) {
sleep(1);
Co\go(function () {
file_get_contents('https://www.baidu.com/');
});
}
});
}🐛 Bug Fixed:
- Fixed the issue where installation via
peclwas not possible. @remicollet - Fixed the bug where setting
keepalivewas not possible forSwoole\Coroutine\FastCGI\Client. @NathanFreeman - Fixed the issue where exceeding the
max_input_varswould throw an error, causing the process to restart repeatedly. @NathanFreeman - Fixed unknown issues caused by using
Swoole\Event::wait()within a coroutine. @matyhtf - Fixed the problem where
proc_opendoes not support pty in coroutine mode. @matyhtf - Fixed segmentation fault issues with
pdo_sqliteon PHP 8.3. @NathanFreeman - Fixed unnecessary warnings during the compilation of
Swoole. @Appla @NathanFreeward - Fixed the error thrown by zend_fetch_resource2_ex when
STDOUT/STDERRare already closed. @Appla @matyhtf - Fixed ineffective
set_tcp_nodelayconfiguration. @matyhtf - Fixed the occasional unreachable branch issue during file upload. @NathanFreeman
- Fixed the problem where setting
dispatch_funcwould cause PHP's internals to throw errors. @NathanFreeman - Fixed the deprecation of AC_PROG_CC_C99 in autoconf >= 2.70. @petk
- Capture exceptions when thread creation fails. @matyhtf
- Fixed the undefined problem with
_tsrm_ls_cache. @jingjingxyk - Fixed the fatal compile error with
GCC 14. @remicollet
⭐️ Kernel optimization:
- Removed unnecessary checks for
socket structs. @petk - Upgraded Swoole Library. @deminy
- Added support for status code 451 in
Swoole\Http\Response. @abnegate - Synchronized
fileoperation code across different PHP versions. @NathanFreeman - Synchronized
pdooperation code across different PHP versions. @NathanFreeman - Optimized the code for
Socket::ssl_recv(). @matyhtf - Improved config.m4; some configurations can now set library locations via
pkg-config. @NathanFreeman - Optimized the use of dynamic arrays during
request header parsing. @NathanFreeman - Optimized file descriptor
fdlifecycle issues in multi-threading mode. @matyhtf - Optimized some fundamental coroutine logic. @matyhtf
❌ Deprecated:
- No longer supports
PHP 8.0. - No longer supports
Swoole\Coroutine\MySQLcoroutine client. - No longer supports
Swoole\Coroutine\Rediscoroutine client. - No longer supports
Swoole\Coroutine\PostgreSQLcoroutine client.
⚠ Warning:
Swoole-v6.0.0-alphais a test version and cannot be used in any production environment; it is for testing purposes only.
😊 Thank you
- Thank you for your contribution to Swoole v6.0.0. Wish you good health, all the best, and smooth work.
✨ 新特性:
Swoole支持多线程模式,当php是zts模式,编译Swoole时开启--enable-swoole-thread时,就能使用多线程模式。- 新增线程管理类
Swoole\Thread。 @matyhtf - 新增线程锁
Swoole\Thread\Lock。 @matyhtf - 新增线程原子计数
Swoole\Thread\Atomic,Swoole\Thread\Atomic\Long。 @matyhtf - 新增安全并发容器
Swoole\Thread\Map,Swoole\Thread\ArrayList,Swoole\Thread\Queue。 @matyhtf - 文件异步操作支持
iouring作为底层引擎,安装了liburing和编译Swoole时开启--enable-iouring,file_get_contents,file_put_contents,fopen,fclose,fread,fwrite,mkdir,unlink,fsync,fdatasync,rename,fstat,lstat,filesize这些函数的异步操作将会由iouring实现。 @matyhtf @NathanFreeman - 升级
Boost Context版本到1.84。现在,龙芯CPU也能够支持协程了。 @NathanFreeman
📖 示例:
- 创建线程
use Swoole\Thread;
$args = Thread::getArguments(); // 如果是主线程,$args 为空,如果是子线程,$args 不为空
$c = 4;
if (empty($args)) {
# 主线程
for ($i = 0; $i < $c; $i++) {
$threads[] = new Thread(__FILE__, $i);
}
for ($i = 0; $i < $c; $i++) {
$threads[$i]->join();
}
} else {
# 子线程
echo "Thread #" . $args[0] . "\n";
while (1) {
sleep(1);
file_get_contents('https://www.baidu.com/');
}
}- 线程 + 服务端(异步风格)
use Swoole\Process;
use Swoole\Thread;
use Swoole\Http\Server;
$http = new Server("0.0.0.0", 9503, SWOOLE_THREAD);
$http->set([
'worker_num' => 2,
'task_worker_num' => 3,
'bootstrap' => __FILE__,
// 通过init_arguments实现线程间的数据共享。
'init_arguments' => function () use ($http) {
$map = new Swoole\Thread\Map;
return [$map];
}
]);
$http->on('Request', function ($req, $resp) use ($http) {
$resp->end('hello world');
});
$http->on('pipeMessage', function ($http, $srcWorkerId, $msg) {
echo "[worker#" . $http->getWorkerId() . "]\treceived pipe message[$msg] from " . $srcWorkerId . "\n";
});
$http->addProcess(new Process(function () {
echo "user process, id=" . Thread::getId();
sleep(2000);
}));
$http->on('Task', function ($server, $taskId, $srcWorkerId, $data) {
var_dump($taskId, $srcWorkerId, $data);
return ['result' => uniqid()];
});
$http->on('Finish', function ($server, $taskId, $data) {
var_dump($taskId, $data);
});
$http->on('WorkerStart', function ($serv, $wid) {
// 通过Swoole\Thread::getArguments()获取配置中的init_arguments传递的共享数据
var_dump(Thread::getArguments(), $wid);
});
$http->on('WorkerStop', function ($serv, $wid) {
var_dump('stop: T' . Thread::getId());
});
$http->start();- Thread + Coroutine 在线程中使用协程
use Swoole\Thread;
$args = Thread::getArguments(); // If it is main thread, the $args is empty; if it is a child thread, the $args is not empty.
$c = 4;
if (empty($args)) {
# main thread
for ($i = 0; $i < $c; $i++) {
$threads[] = new Thread(__FILE__, $i);
}
for ($i = 0; $i < $c; $i++) {
$threads[$i]->join();
}
} else {
# child thread x 4
echo "Thread #" . $args[0] . "\n";
Co\run(function() {
while (1) {
sleep(1);
Co\go(function () {
file_get_contents('https://www.baidu.com/');
});
}
});
}🐛 Bug修复:
- 修复无法通过
pecl安装的问题。 @remicollet - 修复
Swoole\Coroutine\FastCGI\Client客户端无法设置keepalive。 @NathanFreeman - 修复请求参数超过
max_input_vars时会抛出错误导致进程不断重启的问题。 @NathanFreeman - 修复在协程中使用
Swoole\Event::wait()导致的未知问题。 @matyhtf - 修复
proc_open在协程化的时候不支持pty的问题。 @matyhtf - 修复
pdo_sqlite在PHP8.3会出现段错误的问题。 @NathanFreeman - 修复编译
Swoole时的无用警告。 @Appla @NathanFreeman - 修复如果
STDOUT/STDERR已经关闭时,底层调用zend_fetch_resource2_ex会抛出错误。 @Appla @matyhtf - 修复无效的
set_tcp_nodelay配置。 @matyhtf - 修复文件上传的时候偶尔会触发不可达的分支问题。 @NathanFreeman
- 修复设置了
dispatch_func,会导致php底层抛出错误的问题。 @NathanFreeman - 修复AC_PROG_CC_C99在autoconf >= 2.70版本中已过时。 @petk
- 当线程创建失败时,捕获其抛出的异常。 @matyhtf
- 修复
_tsrm_ls_cache未定义问题。 @jingjingxyk - 修复在
GCC 14编译会导致致命错误。 @remicollet
⭐️ 内核优化:
- 移除对
socket structs的无用检查。 @petk - 升级swoole Library。 @deminy
Swoole\Http\Response增加对451状态码的支持。 @abnegate- 同步PHP不同版本的
文件操作代码。 @NathanFreeman - 同步PHP不同版本的
pdo操作代码。 @NathanFreeman - 优化
Socket::ssl_recv()的代码。 @matyhtf - 优化了config.m4,一些配置可以通过
pkg-config设置依赖库位置。 @NathanFreeman - 优化
解析请求头的时候使用动态数组的问题 。 @NathanFreeman - 优化在多线程模式下,文件描述符
fd的生命周期问题。 @matyhtf - 优化协程一些基本逻辑。 @matyhtf
❌ 废弃:
- 不再支持
PHP 8.0。 - 不再支持
Swoole\Coroutine\MySQL协程客户端。 - 不再支持
Swoole\Coroutine\Redis协程客户端。 - 不再支持
Swoole\Coroutine\PostgreSQL协程客户端。
⚠ 注意:
Swoole-v6.0.0-alpha是测试版本,不能用于任何生产环境,只能用于测试。
😊 致谢
- 感谢你们为Swoole v6.0.0做出的贡献,祝愿大家身体健康,万事如意,工作顺利。