diff --git a/public/zh-cn/_sidebar.md b/public/zh-cn/_sidebar.md
index a58552a..7c5d402 100644
--- a/public/zh-cn/_sidebar.md
+++ b/public/zh-cn/_sidebar.md
@@ -9,7 +9,7 @@
* [HTTP服务器](start/start_http_server.md)
* [WebSocket服务器](start/start_ws_server.md)
* [MQTT(物联网)服务器](start/start_mqtt.md)
- * [执行异步任务(Task)](start/start_task.md)
+ * [执行异步任务](start/start_task.md)
* [协程初探](start/coroutine.md)
* [服务端(异步风格)](server/init.md)
@@ -41,46 +41,45 @@
* [MySQL客户端](coroutine_client/mysql.md)
* [Redis客户端](coroutine_client/redis.md)
+* 进程管理 (Process)
+ * [创建进程](process/process.md)
+ * [进程池](process/process_pool.md)
+ * [进程管理器](process/process_manager.md)
+
+* 线程管理 (Thread)
+ * [创建线程](thread/thread.md)
+ * [线程池](thread/pool.md)
+ * [方法与属性](thread/info)
+ * [并发Map](thread/map.md)
+ * [并发List](thread/arraylist.md)
+ * [并发Queue](thread/queue.md)
+ * [数据类型](thread/transfer.md)
+
* [协程 (Coroutine)](coroutine.md)
* [一键协程化](runtime.md)
- * [核心API](coroutine/coroutine.md)
- * [协程容器](coroutine/scheduler.md)
+ * [协程容器](coroutine/scheduler.md)
+ * [协程API](coroutine/coroutine.md)
* [系统API](coroutine/system.md)
- * [进程API](coroutine/proc_open.md)
- * [Channel](coroutine/channel.md)
- * [WaitGroup](coroutine/wait_group.md)
- * [Barrier](coroutine/barrier.md)
* [并发调用](coroutine/multi_call.md)
* [连接池](coroutine/conn_pool.md)
* [Library](library.md)
* [调试协程](coroutine/gdb.md)
* [编程须知](coroutine/notice.md)
+* 进程/线程/协程同步
+ * [锁](memory/lock.md)
+ * [原子计数](memory/atomic.md)
+ * [同步屏障](thread/barrier.md)
+ * [高性能共享内存](memory/table.md)
+ * [Channel](coroutine/channel.md)
+ * [WaitGroup](coroutine/wait_group.md)
+
* 文件异步操作
* [实现](file/engine.md)
* [配置](file/setting.md)
-* 线程管理 (Thread)
- * [创建线程](thread/thread.md)
- * [线程池(Thread\Pool)](thread/pool.md)
- * [方法与属性](thread/info)
- * [并发Map](thread/map.md)
- * [并发List](thread/arraylist.md)
- * [并发Queue](thread/queue.md)
- * [同步屏障Barrier](thread/barrier.md)
- * [数据类型](thread/transfer.md)
-
-* 进程管理 (Process)
- * [创建进程](process/process.md)
- * [进程池(Process\Pool)](process/process_pool.md)
- * [进程管理器(Process\Manager)](process/process_manager.md)
- * [高性能共享内存(Table)](memory/table.md)
-
-* 并发管理
- * [锁(Lock)](memory/lock.md)
- * [原子计数(Atomic)](memory/atomic.md)
- * [事件循环(EventLoop)](event.md)
- * [定时器(Timer)](timer.md)
+* [事件循环(EventLoop)](event.md)
+* [定时器(Timer)](timer.md)
* 其他
* [常量](consts.md)
diff --git a/public/zh-cn/coroutine/barrier.md b/public/zh-cn/coroutine/barrier.md
index 27fa7a2..72621b3 100644
--- a/public/zh-cn/coroutine/barrier.md
+++ b/public/zh-cn/coroutine/barrier.md
@@ -1,4 +1,4 @@
-# Coroutine\Barrier
+# 协程同步执行屏障 Barrier
在 [Swoole Library](https://github.com/swoole/library) 中底层提供了一个更便捷的协程并发管理工具:`Coroutine\Barrier` 协程屏障,或者叫协程栅栏。基于 `PHP` 引用计数和 `Coroutine API` 实现。
@@ -6,6 +6,8 @@
!> Swoole 版本 >= v4.5.5 时可用。
+!> 该协程屏障只能用于单进程或者单线程中的多协程同步,主要作用还是让主协程等待全部子协程完成任务后再退出。
+
## 使用示例
```php
@@ -33,6 +35,32 @@ run(function () {
});
```
+## 方法
+
+### make()
+生成一个协程屏障。
+
+```php
+Coroutine\Barrier::make(): self
+```
+
+### wait()
+在所有协程还未完成任务时,主协程在该函数等待所有协程完成任务。
+
+```php
+Coroutine\Barrier::wait(Barrier &$barrier, float $timeout = -1): void
+```
+
+* **参数**
+ * `int $barrier`
+ * 功能:由`Coroutine\Barrier::make()`返回的协程屏障。
+ * 默认值:无。
+ * 其它值:无。
+ * `float $timeout`
+ * 功能:超时时间。
+ * 默认值:-1,表示永不超时。
+ * 其它值:无。
+
## 执行流程
* 先使用`Barrier::make()`创建了一个新的协程屏障
diff --git a/public/zh-cn/coroutine/channel.md b/public/zh-cn/coroutine/channel.md
index 2e0394e..ee97631 100644
--- a/public/zh-cn/coroutine/channel.md
+++ b/public/zh-cn/coroutine/channel.md
@@ -1,4 +1,4 @@
-# Coroutine\Channel
+# Channel
> 建议先查看[概览](/coroutine),了解一些协程基本概念后再看此节。
diff --git a/public/zh-cn/coroutine/coroutine.md b/public/zh-cn/coroutine/coroutine.md
index 4966394..ee89848 100644
--- a/public/zh-cn/coroutine/coroutine.md
+++ b/public/zh-cn/coroutine/coroutine.md
@@ -569,6 +569,8 @@ Swoole\Coroutine::getElapsed([$cid]): int
!> Swoole版本 >= `v4.7.0` 可用
+!> 你无法取消正在进行文件IO的协程,因为此时内核正在进行文件读写操作,如果此时取消协程,会导致内核正在操作的内存被释放导致段错误。
+
```php
Swoole\Coroutine::cancel($cid): bool
```
diff --git a/public/zh-cn/coroutine/notice.md b/public/zh-cn/coroutine/notice.md
index 4a98e0c..a141a9b 100644
--- a/public/zh-cn/coroutine/notice.md
+++ b/public/zh-cn/coroutine/notice.md
@@ -14,6 +14,13 @@
!> `hook`这两个入口函数后,大部分情况下会把平坦的PHP指令调用变为`C`函数调用,增加C栈的消耗。
+## 协程中创建进程
+
+由于在协程空间内`fork`进程会带着其他协程上下文,因此底层禁止了在`Coroutine`中使用`Process`模块。可以使用
+
+* `System::exec()`或`Runtime Hook`+`shell_exec`实现外面程序运行
+* `Runtime Hook`+`proc_open`实现父子进程交互通信
+
## 退出协程
在Swoole低版本中,协程中使用`exit`强行退出脚本会导致内存错误导致不可预期的结果或`coredump`,在Swoole服务中使用`exit`会使整个服务进程退出且内部的协程全部异常终止导致严重问题,Swoole长期以来一直禁止开发者使用`exit`,但开发者可以使用抛出异常这种非常规的方式,在顶层`catch`来实现和`exit`相同的退出逻辑
diff --git a/public/zh-cn/coroutine/scheduler.md b/public/zh-cn/coroutine/scheduler.md
index b62bdeb..354bfd9 100644
--- a/public/zh-cn/coroutine/scheduler.md
+++ b/public/zh-cn/coroutine/scheduler.md
@@ -1,65 +1,29 @@
-# Coroutine\Scheduler
-
-?> 所有的[协程](/coroutine)必须在`协程容器`里面[创建](/coroutine/coroutine?id=create),`Swoole`程序启动的时候大部分情况会自动创建`协程容器`,用`Swoole`启动程序的方式一共有三种:
+# 协程容器
+所有的[协程](/coroutine)必须在`协程容器`里面[创建](/coroutine/coroutine?id=create),`Swoole`程序启动的时候大部分情况会自动创建`协程容器`,用`Swoole`启动程序的方式一共有三种:
- 调用[异步风格](/server/init)服务端程序的[start](/server/methods?id=start)方法,此种启动方式会在事件回调中创建`协程容器`,参考[enable_coroutine](/server/setting?id=enable_coroutine)。
- 调用`Swoole`提供的2个进程管理模块[Process](/process/process)和[Process\Pool](/process/process_pool)的[start](/process/process_pool?id=start)方法,此种启动方式会在进程启动的时候创建`协程容器`,参考这两个模块构造函数的`enable_coroutine`参数。
- - 其他直接裸写协程的方式启动程序,需要先创建一个协程容器(`Coroutine\run()`函数,可以理解为java、c的`main`函数),例如:
-
-* **启动一个全协程`HTTP`服务**
-
-```php
-use Swoole\Coroutine\Http\Server;
-use function Swoole\Coroutine\run;
-
-run(function () {
- $server = new Server('127.0.0.1', 9502, false);
- $server->handle('/', function ($request, $response) {
- $response->end("
Index
");
- });
- $server->handle('/test', function ($request, $response) {
- $response->end("Test
");
- });
- $server->handle('/stop', function ($request, $response) use ($server) {
- $response->end("Stop
");
- $server->shutdown();
- });
- $server->start();
-});
-echo 1;//得不到执行
-```
+ - 其他直接裸写协程的方式启动程序,需要先创建一个协程容器`Coroutine\Scheduler`(可以理解为java、c的`main`函数),协程容器会初始化完毕运行协程所需的环境。
-* **添加2个协程并发的做一些事情**
+!> 在`Swoole v4.4+`版本可用。
+## 使用示例
```php
-use Swoole\Coroutine;
-use function Swoole\Coroutine\run;
-
-run(function () {
- Coroutine::create(function() {
- var_dump(file_get_contents("http://www.xinhuanet.com/"));
- });
+use Swoole\Coroutine\Scheduler;
- Coroutine::create(function() {
- Coroutine::sleep(1);
- echo "done\n";
- });
+$scheduler = new Scheduler();
+$scheduler->set(['hook_flags' => SWOOLE_HOOK_ALL]);
+$scheduler->add(function() {
+ sleep(1);
});
-echo 1;//可以得到执行
+return $scheduler->start();
```
-!> 在`Swoole v4.4+`版本可用。
-
-!> 不可以嵌套`Coroutine\run()`。
-`Coroutine\run()`里面的逻辑如果有未处理的事件在`Coroutine\run()`之后就进行[EventLoop](learn?id=什么是eventloop),后面的代码将得不到执行,反之,如果没有事件了将继续向下执行,可以再次`Coroutine\run()`。
-
-上文的`Coroutine\run()`函数其实是对`Swoole\Coroutine\Scheduler`类(协程调度器类)的封装,想了解细节的同学可以看`Swoole\Coroutine\Scheduler`的方法:
+## 方法
### set()
-?> **设置协程运行时参数。**
-
-?> 是`Coroutine::set`方法的别名。请参考 [Coroutine::set](/coroutine/coroutine?id=set) 文档
+?> **设置协程运行时参数。** ,是`Coroutine::set`方法的别名。请参考 [Coroutine::set](/coroutine/coroutine?id=set) 文档。
```php
Swoole\Coroutine\Scheduler->set(array $options): bool
@@ -74,9 +38,7 @@ $sch->set(['max_coroutine' => 100]);
### getOptions()
-?> **获取设置的协程运行时参数。** Swoole版本 >= `v4.6.0` 可用
-
-?> 是`Coroutine::getOptions`方法的别名。请参考 [Coroutine::getOptions](/coroutine/coroutine?id=getoptions) 文档
+?> **获取设置的协程运行时参数。** Swoole版本 >= `v4.6.0` 可用,是`Coroutine::getOptions`方法的别名。请参考 [Coroutine::getOptions](/coroutine/coroutine?id=getoptions) 文档。
```php
Swoole\Coroutine\Scheduler->getOptions(): null|array
@@ -177,4 +139,58 @@ Swoole\Coroutine\Scheduler->start(): bool
* **返回值**
* 启动成功,会执行所有添加的任务,所有协程退出时`start`会返回`true`
- * 启动失败返回`false`,原因可能是已经启动了或者已经创建了其他调度器无法再次创建
\ No newline at end of file
+ * 启动失败返回`false`,原因可能是已经启动了或者已经创建了其他调度器无法再次创建
+
+
+## 简化函数
+为了简化创建协程容器的步骤,`Swoole`封装了一个`Coroutine\run()`函数。
+
+### 使用示例
+* **启动一个全协程`HTTP`服务**
+
+```php
+use Swoole\Coroutine\Http\Server;
+use function Swoole\Coroutine\run;
+
+run(function () {
+ $server = new Server('127.0.0.1', 9502, false);
+ $server->handle('/', function ($request, $response) {
+ $response->end("Index
");
+ });
+ $server->handle('/test', function ($request, $response) {
+ $response->end("Test
");
+ });
+ $server->handle('/stop', function ($request, $response) use ($server) {
+ $response->end("Stop
");
+ $server->shutdown();
+ });
+ $server->start();
+});
+echo 1;//得不到执行
+```
+
+* **添加2个协程并发的做一些事情**
+
+```php
+use Swoole\Coroutine;
+use function Swoole\Coroutine\run;
+
+run(function () {
+ Coroutine::create(function() {
+ var_dump(file_get_contents("http://www.xinhuanet.com/"));
+ });
+
+ Coroutine::create(function() {
+ Coroutine::sleep(1);
+ echo "done\n";
+ });
+});
+echo 1;//可以得到执行
+```
+
+!> 使用`Coroutine\run()`函数需要确保`swoole.enable_library=On`(默认为On),因为该函数是通过`library`提供的。
+
+!> 使用协程容器会默认设置一键协程化,使所有的PHP阻塞操作变成非阻塞操作。
+
+!> 不可以嵌套`Coroutine\run()`。`Coroutine\run()`里面的逻辑如果有未处理的事件在`Coroutine\run()`之后就进行[EventLoop](learn?id=什么是eventloop),后面的代码将得不到执行,反之,如果没有事件了将继续向下执行,可以再次`Coroutine\run()`。
+
diff --git a/public/zh-cn/coroutine/wait_group.md b/public/zh-cn/coroutine/wait_group.md
index 8bba6bb..9fc8c04 100644
--- a/public/zh-cn/coroutine/wait_group.md
+++ b/public/zh-cn/coroutine/wait_group.md
@@ -2,14 +2,7 @@
在`Swoole4`中可以使用[Channel](/coroutine/channel)实现协程间的通信、依赖管理、协程同步。基于[Channel](/coroutine/channel)可以很容易地实现`Golang`的`sync.WaitGroup`功能。
-## 实现代码
-
-> 此功能是使用PHP编写的功能,并不是C/C++代码,实现源代码在 [Library](https://github.com/swoole/library/blob/master/src/core/Coroutine/WaitGroup.php) 当中
-
-* `add`方法增加计数
-* `done`表示任务已完成
-* `wait`等待所有任务完成恢复当前协程的执行
-* `WaitGroup`对象可以复用,`add`、`done`、`wait`之后可以再次使用
+!> `WaitGroup`只能用于单进程或者单线程中的多协程同步,主要作用还是让主协程等待全部子协程完成任务。
## 使用示例
@@ -69,4 +62,34 @@ run(function () {
//这里 $result 包含了 2 个任务执行结果
var_dump($result);
});
-```
\ No newline at end of file
+```
+
+## 方法
+
+### __construct
+`WaitGroup`的构造函数。
+
+```php
+Swoole\Coroutine\WaitGroup->__construct()
+```
+
+### add
+在子协程中使用,表示引用计数加1。
+
+```php
+Swoole\Coroutine\WaitGroup->add(): void
+```
+
+### done
+在子协程中使用,表示任务已完成,引用计数减一。
+
+```php
+Swoole\Coroutine\WaitGroup->done(): void
+```
+
+### wait
+在主协程中使用,主协程会等待子协程全部任务完成之后再退出。
+
+```php
+Swoole\Coroutine\WaitGroup->wait(): void
+```
diff --git a/public/zh-cn/environment.md b/public/zh-cn/environment.md
index ded165d..89911bb 100644
--- a/public/zh-cn/environment.md
+++ b/public/zh-cn/environment.md
@@ -85,6 +85,20 @@ pecl install -D 'enable-sockets="no" enable-openssl="yes" enable-http2="yes" ena
pecl install --configureoptions 'enable-sockets="no" enable-openssl="yes" enable-http2="yes" enable-mysqlnd="yes" enable-swoole-json="no" enable-swoole-curl="yes" enable-cares="yes"' swoole
```
+## PIE
+
+Swoole 项目支持由 PHP 全新的扩展安装工具 PIE 一键下载安装。
+
+```shell
+pie install swoole/swoole:5.1.5
+```
+
+通过 PIE 安装 Swoole 时,在安装过程中它会询问是否要启用某些功能,这也可以在运行安装之前提供,例如:
+
+```shell
+pie install swoole/swoole:5.1.5 --enable-socket --enable-swoole-curl
+```
+
## 添加Swoole到php.ini
最后,编译安装成功后,修改`php.ini`加入
@@ -225,6 +239,14 @@ with-swoole-odbc="unixODBC,/usr"
>`v6.0`版本后可用,而且需要安装`liburing`依赖来支持此特性,如果磁盘性能够好的情况下两种模式性能相差不大,只有`I/O`压力较大的情况下,`iouring`模式性能会优于异步线程模式。
+>`io_uring`对linux内核版本要求较高,建议在linux 5.12+,liburing 2.6+ 以上的系统使用。
+
+#### --enable-zstd
+
+添加这个编译选项后,`http`服务端和客户端之间可以使用高性能压缩工具`Zstd`压缩响应。
+
+>`v6.0`版本后可用,而且需要安装`libzstd`依赖来支持此特性。
+
### 特殊参数
!> **如无历史原因不建议启用**
diff --git a/public/zh-cn/event.md b/public/zh-cn/event.md
index 65a28f7..a53c04a 100644
--- a/public/zh-cn/event.md
+++ b/public/zh-cn/event.md
@@ -1,6 +1,6 @@
# Event
-`Swoole`扩展还提供了直接操作底层`epoll/kqueue`事件循环的接口。可将其他扩展创建的`socket`,`PHP`代码中`stream/socket`扩展创建的`socket`等加入到`Swoole`的[EventLoop](/learn?id=什么是eventloop)中,
+`Swoole`扩展还提供了直接操作底层`epoll/kqueue/poll/select`事件循环的接口。可将其他扩展创建的`socket`,`PHP`代码中`stream/socket`扩展创建的`socket`等加入到`Swoole`的[EventLoop](/learn?id=什么是eventloop)中,
否则第三方的$fd如果是同步IO会导致Swoole的EventLoop得不到执行,[参考案例](/learn?id=同步io转换成异步io)。
!> `Event`模块比较底层,是`epoll`的初级封装,使用者最好有IO多路复用编程经验。
@@ -41,9 +41,9 @@ Swoole\Event::add(mixed $sock, callable $read_callback, callable $write_callback
* **其它值**:无
* **`int $flags`**
- * **功能**:事件类型的掩码【可选择关闭/开启可读可写事件,如`SWOOLE_EVENT_READ`、`SWOOLE_EVENT_WRITE`或者`SWOOLE_EVENT_READ|SWOOLE_EVENT_WRITE`】
+ * **功能**:事件类型的掩码
* **默认值**:无
- * **其它值**:无
+ * **其它值**:`SWOOLE_EVENT_READ`监听可读事件,`SWOOLE_EVENT_WRITE`监听可写事件,`SWOOLE_EVENT_READ|SWOOLE_EVENT_WRITE`同时监听可读可写事件
* **$sock 4种类型**
@@ -58,7 +58,7 @@ object | `Swoole\Process`或`Swoole\Client`,底层自动转换为[UnixSocket](
* 添加事件监听成功成功返回`true`
* 添加失败返回`false`,请使用`swoole_last_error`获取错误码
- * 已添加过的`socket`不能重复添加,可以使用`swoole_event_set`修改`socket`对应的回调函数和事件类型
+ * 已添加过的`socket`不能重复添加,重复添加同一个`socket`会抛出错误。可以使用`swoole_event_set`修改`socket`对应的回调函数和事件类型
!> 使用`Swoole\Event::add`将`socket`加入到事件监听后,底层会自动将该`socket`设置为非阻塞模式
@@ -95,9 +95,10 @@ Swoole\Event::set($fd, mixed $read_callback, mixed $write_callback, int $flags):
* **参数**
* 参数与[Event::add](/event?id=add)完全相同。如果传入`$fd`在[EventLoop](/learn?id=什么是eventloop)中不存在返回`false`。
- * 当`$read_callback`不为`null`时,将修改可读事件回调函数为指定的函数
- * 当`$write_callback`不为`null`时,将修改可写事件回调函数为指定的函数
- * `$flags`可关闭/开启,可写(`SWOOLE_EVENT_READ`)和可读(`SWOOLE_EVENT_WRITE`)事件的监听
+ * 当`$read_callback`不为`null`时,将修改可读事件回调函数为指定的函数。
+ * 当`$write_callback`不为`null`时,将修改可写事件回调函数为指定的函数。
+ * 如果`$flags`为`SWOOLE_EVENT_READ`,意味着只监听可读事件,停止监听可写事件。
+ * 如果`$flags`为`SWOOLE_EVENT_WRITE`,意味着只监听可写事件,停止监听可读事件。
!> 注意如果监听了`SWOOLE_EVENT_READ`事件,而当前并未设置`read_callback`,底层会直接返回`false`,添加失败。`SWOOLE_EVENT_WRITE`同理。
@@ -198,9 +199,9 @@ Event::add($fp, function($fp) {
Event::write($fp, $data);
```
-#### SOCKET缓存区已满后,Swoole的底层逻辑
+#### socket缓存区已满后,Swoole的底层逻辑
-持续写入`SOCKET`如果对端读取不够快,那`SOCKET`缓存区会塞满。`Swoole`底层会将数据存到内存缓存区中,直到可写事件触发再写入`SOCKET`。
+持续写入`socket`如果对端读取不够快,那`socket`缓存区会塞满。`Swoole`底层会将数据存到内存缓存区中,直到可写事件触发再写入`socket`。
如果内存缓存区也被写满了,此时`Swoole`底层会抛出`pipe buffer overflow, reactor will block.`错误,并进入阻塞等待。
diff --git a/public/zh-cn/file/engine.md b/public/zh-cn/file/engine.md
index 1ffb740..bc3394c 100644
--- a/public/zh-cn/file/engine.md
+++ b/public/zh-cn/file/engine.md
@@ -1,4 +1,4 @@
-# 异步文件操作
+# 文件异步操作
`Swoole`的[一键协程化](/runtime)可以很方便的将`PHP`的文件操作由同步阻塞变为异步执行,`Swoole`一共内置了两种不同的文件异步策略。
@@ -13,13 +13,12 @@
* `io_uring`是`Swoole v6.0`之后内置的策略,基于`io_uring`和`epoll`实现异步。
* 吞吐量高,可以处理大量文件异步操作。
-* 对`linux`版本有要求,也需要依赖`liburing`这个共享库,有些操作系统没法使用这个特性。
-* 由于是基于`文件描述符`实现文件异步,只支持少数`PHP`的文件操作函数。
-* 对linux内核版本要求较高。
+* `io_uring`对linux内核版本要求较高,建议在linux 5.12+,liburing 2.6+ 以上的系统使用,有些操作系统没法使用这个特性。
+* 由于是基于`文件描述符`实现文件异步,只支持一些`PHP`的文件操作函数。
!> 当系统安装了`liburing`和编译`Swoole`开启了`--enable-iouring`之后才能使用。
!> 开启了`io_uring`之后并不会替换掉`线程池`模式,有些`io_uring`没法协程化的函数还是会让`线程池`处理。
-!> `io_uring`只能处理`file_get_contents`,`file_put_contents`,`fopen`,`fclose`,`fread`,`fwrite`,`mkdir`,`unlink`,`fsync`,`fdatasync`,`rename`,`fstat`,`lstat`,`filesize`函数。
+!> `io_uring`只能协程化`file_get_contents`,`file_put_contents`,`fopen`,`fclose`,`fread`,`fwrite`,`mkdir`,`unlink`,`fsync`,`fdatasync`,`rename`,`fstat`,`lstat`,`filesize`函数。
diff --git a/public/zh-cn/file/setting.md b/public/zh-cn/file/setting.md
index db31adc..6171de8 100644
--- a/public/zh-cn/file/setting.md
+++ b/public/zh-cn/file/setting.md
@@ -7,20 +7,22 @@
```php
10,
'aio_worker_num' => 20,
'aio_max_wait_time' => 60,
'aio_max_idle_time' => 60,
- 'iouring_entries' => 1024
+ 'iouring_entries' => 1024,
+ 'iouring_workers' => 16,
+ 'iouring_flag' => SWOOLE_IOURING_SQPOLL
]);
$server = new Swoole\Server('127.0.0.1', 9501);
$server->set([
- 'aio_core_worker_num' => 10,
'aio_worker_num' => 20,
'aio_max_wait_time' => 60,
'aio_max_idle_time' => 60,
- 'iouring_entries' => 1024
+ 'iouring_entries' => 1024,
+ 'iouring_workers' => 16,
+ 'iouring_flag' => SWOOLE_IOURING_SQPOLL
]);
```
@@ -46,6 +48,25 @@ $server->set([
!> 如果传入的值过大,内核会抛出异常并且终止程序。
+!> 当系统安装了`liburing`和编译``Swoole v6.0`以上的版本,开启了`--enable-iouring`之后才能使用。
+
+### iouring_workers
+
+?> 设置`io_uring`的工作线程数,默认值是`CPU 核数 * 4`。
+
+!> 如果传入的值过大,内核会抛出异常并且终止程序。
+
!> 当系统安装了`liburing`和编译`Swoole`开启了`--enable-iouring`之后才能使用。
-!> 当系统安装了`liburing`和编译``Swoole v6.0`以上的版本,开启了`--enable-iouring`之后才能使用。
+### iouring_flag
+
+?> 设置`io_uring`的工作模式,默认值为`SWOOLE_IOURING_DEFAULT`。
+
+- `SWOOLE_IOURING_DEFAULT`,中断驱动模式,可通过系统调用`io_uring_enter`提交`I/O`请求,然后直接检查完成队列状态判断是否完成。
+- `SWOOLE_IOURING_SQPOLL`,内核轮询模式,内核会创建内核线程用于提交和收割`I/O`请求,几乎完全消除用户态内核态上下文切换,性能较好。
+
+!> 如果传入的模式不正确,内核会统一使用`SWOOLE_IOURING_DEFAULT`中断驱动模式。
+
+!> `SWOOLE_IOURING_SQPOLL`是通过牺牲一部分CPU性能换取更高的磁盘读写性能(IOPS),因此QPS会比默认模式差。
+
+!> 如果服务压力不大,可以使用`SWOOLE_IOURING_DEFAULT`获取更高的QPS,如果确定服务性能瓶颈是在磁盘,可以使用`SWOOLE_IOURING_SQPOLL`。
diff --git a/public/zh-cn/http_server.md b/public/zh-cn/http_server.md
index 13c1208..a350fc9 100644
--- a/public/zh-cn/http_server.md
+++ b/public/zh-cn/http_server.md
@@ -992,7 +992,7 @@ $server->set([
### upload_max_filesize
-?> **设置上传文件的最大值**
+?> **设置上传文件的最大值,设置该值后,上传文件大小大于`package_max_length`时程序不会报错,而是将会文件内容存储到临时文件中,不保存在内存中,方便大文件上传。**
```php
$server->set([
diff --git a/public/zh-cn/memory/atomic.md b/public/zh-cn/memory/atomic.md
index 235153d..5af0902 100644
--- a/public/zh-cn/memory/atomic.md
+++ b/public/zh-cn/memory/atomic.md
@@ -1,4 +1,4 @@
-# 进程/线程间无锁计数器 Atomic
+# 无锁计数器 Atomic
`Atomic`是`Swoole`底层提供的原子计数操作类,可以方便整数的无锁原子增减。
@@ -58,9 +58,11 @@ Swoole\Atomic::__construct(int $init_value = 0);
* **默认值**:`0`
* **其它值**:无
-!> -`Atomic`只能操作`32`位无符号整数,最大支持`42`亿,不支持负数;
--在`Server`中使用原子计数器,必须在`Server->start`前创建;
--在[Process](/process/process)中使用原子计数器,必须在`Process->start`前创建。
+!> `Atomic`只能操作`32`位无符号整数,最大支持`42`亿,不支持负数。
+
+!> 在`Server`中使用原子计数器,必须在`Server->start`前创建。
+
+!> 在[Process](/process/process)中使用原子计数器,必须在`Process->start`前创建。
### add()
@@ -178,8 +180,11 @@ Swoole\Atomic->wait(float $timeout = 1.0): bool
`wait`会阻塞整个进程而不是协程,因此请勿在协程环境中使用`Atomic->wait()`避免引起进程挂起。
-!> -使用`wait/wakeup`特性时,原子计数的值只能为`0`或`1`,否则会导致无法正常使用;
--当然原子计数的值为`1`时,表示不需要进入等待状态,资源当前就是可用。`wait`函数会立即返回`true`。
+!> 使用`wait/wakeup`特性时,原子计数的值只能为`0`或`1`,否则会导致无法正常使用。
+
+!> 当然原子计数的值为`1`时,表示不需要进入等待状态,资源当前就是可用。`wait`函数会立即返回`true`。
+
+!> `wait`会阻塞整个进程而不是协程,因此请勿在协程环境中使用该函数,避免引起进程挂起。
* **使用示例**
diff --git a/public/zh-cn/memory/lock.md b/public/zh-cn/memory/lock.md
index 7163109..3b25a6a 100644
--- a/public/zh-cn/memory/lock.md
+++ b/public/zh-cn/memory/lock.md
@@ -1,17 +1,9 @@
-# 进程/线程间锁 Lock
+# 锁 Lock
-* `PHP`代码中可以很方便地创建一个锁`Swoole\Lock`,用来实现数据同步。`Lock`类支持`5`种锁的类型。
-* 多线程模式需要使用`Swoole\Thread\Lock`,除了命名空间不一样,其接口与 `Swoole\Lock` 完全一致。
-
-锁类型 | 说明
----|---
-SWOOLE_MUTEX | 互斥锁
-SWOOLE_RWLOCK | 读写锁
-SWOOLE_SPINLOCK | 自旋锁
-SWOOLE_FILELOCK | 文件锁(废弃)
-SWOOLE_SEM | 信号量(废弃)
-
-!> 请勿在[onReceive](/server/events?id=onreceive)等回调函数中创建锁,否则内存会持续增长,造成内存泄漏。
+* 使用`Swoole`提供的锁可以很方便代码中实现数据同步。
+* 多进程模式下请使用`Swoole\Lock`,多线程模式下请使用`Swoole\Thread\Lock`,除了命名空间不一样,其接口完全一致。
+* `swoole6.0`引入协程锁`Swoole\Coroutine\Lock`,使得跨进程/线程之间的协程加锁不再阻塞进程,协程锁接口与多进程锁和多线程锁略有不同。
+* 该协程锁默认通过`原子计数`和`sleep`实现可重入的互斥锁,如果`linux`内核为6.7以上,`liburing`版本为2.6以上,编译时`swoole6.0`开启了`--enable-iouring`,协程锁的底层将会替换成`io_uring`的`futex`特性,相关的配置参数可以查看[文件异步操作 - 配置](/file/setting?id=iouring_entries)。
## 使用示例
@@ -38,27 +30,6 @@ sleep(1);
echo "[Master]exit\n";
```
-## 警告
-
-!> 在协程中无法使用锁,请谨慎使用,不要在`lock`和`unlock`操作中间使用可能引起协程切换的`API`。
-
-### 错误示例
-
-!> 此代码在协程模式下`100%`死锁。
-
-```php
-$lock = new Swoole\Lock();
-$c = 2;
-
-while ($c--) {
- go(function () use ($lock) {
- $lock->lock();
- Co::sleep(1);
- $lock->unlock();
- });
-}
-```
-
## 方法
### __construct()
@@ -71,19 +42,22 @@ Swoole\Lock::__construct(int $type = SWOOLE_MUTEX, string $lockfile = '');
!> 不要循环创建/销毁锁的对象,否则会发生内存泄漏。
+!> 协程锁的构造函数不需要传入任何参数。
+
+!> 每一种类型的锁支持的方法都不一样。如读写锁、文件锁可以支持`$lock->lock_read()`。另外除文件锁外,其他类型的锁必须在父进程内创建,这样`fork`出的子进程之间才可以互相争抢锁。
+
* **参数**
* **`int $type`**
* **功能**:锁的类型
* **默认值**:`SWOOLE_MUTEX`【互斥锁】
- * **其它值**:无
+ * **其它值**:`读写锁 SWOOLE_RWLOCK`,`自旋锁 SWOOLE_SPINLOCK`,`文件锁 SWOOLE_FILELOCK (已废弃)`,`信号量 SWOOLE_SEM(已废弃)`
* **`string $lockfile`**
* **功能**:指定文件锁的路径【当类型为`SWOOLE_FILELOCK`时必须传入】
* **默认值**:无
* **其它值**:无
-!> 每一种类型的锁支持的方法都不一样。如读写锁、文件锁可以支持`$lock->lock_read()`。另外除文件锁外,其他类型的锁必须在父进程内创建,这样`fork`出的子进程之间才可以互相争抢锁。
### lock()
@@ -92,6 +66,7 @@ Swoole\Lock::__construct(int $type = SWOOLE_MUTEX, string $lockfile = '');
```php
Swoole\Lock->lock(): bool
```
+* 如果是协程锁,当其他`进程`的协程持有锁,那当前协程`不会阻塞`,而是会让出CPU,等待`唤醒`。
### trylock()
@@ -108,14 +83,6 @@ Swoole\Lock->trylock(): bool
!> `SWOOlE_SEM` 信号量没有`trylock`方法
-### unlock()
-
-释放锁。
-
-```php
-Swoole\Lock->unlock(): bool
-```
-
### lock_read()
只读加锁。
@@ -128,7 +95,9 @@ Swoole\Lock->lock_read(): bool
* 但不能`$lock->lock()`或`$lock->trylock()`,这两个方法是获取独占锁,在独占锁加锁时,其他进程无法再进行任何加锁操作,包括读锁;
* 当另外一个进程获得了独占锁(调用`$lock->lock()`/`$lock->trylock()`)时,`$lock->lock_read()`会发生阻塞,直到持有独占锁的进程释放锁。
-!> 只有`SWOOLE_RWLOCK`和`SWOOLE_FILELOCK`类型的锁支持只读加锁
+!> 协程锁没有`lock_read()`函数。
+
+!> 只有`SWOOLE_RWLOCK`和`SWOOLE_FILELOCK`类型的锁支持只读加锁。
### trylock_read()
@@ -138,6 +107,8 @@ Swoole\Lock->lock_read(): bool
Swoole\Lock->trylock_read(): bool
```
+!> 协程锁没有`trylock_read()`函数。
+
!> 调用会立即返回,必须检测返回值以确定是否拿到了锁。
### lockwait()
@@ -161,4 +132,36 @@ Swoole\Lock->lockwait(float $timeout = 1.0): bool
* 在规定的时间内未获得锁,返回`false`
* 加锁成功返回`true`
+!> 协程锁没有`lockwait()`函数。
+
!> 只有`Mutex`类型的锁支持`lockwait`
+
+### unlock()
+
+释放锁。
+
+```php
+Swoole\Lock->unlock(): bool
+```
+
+## 注意
+!> 请勿在[onReceive](/server/events?id=onreceive)等回调函数中创建锁,否则内存会持续增长,造成内存泄漏。
+
+!> `原子计数`和`sleep`实现的协程锁比起`io_uring`实现的协程锁,性能会较差,因为它会带来不必要的上下文切换。
+
+!> 加锁和解锁必须在同一个进程/线程/协程中完成,不然会破坏竞争条件,无法有效实现互斥。
+
+!> 如果不是使用协程锁,此代码在协程模式下`100%`死锁。
+
+```php
+$lock = new Swoole\Lock();
+$c = 2;
+
+while ($c--) {
+ go(function () use ($lock) {
+ $lock->lock();
+ Co::sleep(1);
+ $lock->unlock();
+ });
+}
+```
diff --git a/public/zh-cn/process/process.md b/public/zh-cn/process/process.md
index 2668d05..4e050be 100644
--- a/public/zh-cn/process/process.md
+++ b/public/zh-cn/process/process.md
@@ -17,7 +17,7 @@ Swoole提供的进程管理模块,用来替代PHP的`pcntl`
* 可以方便的实现进程间通讯
* 支持重定向标准输入和输出,在子进程内`echo`不会打印屏幕,而是写入管道,读键盘输入可以重定向为管道读取数据
* 提供了[exec](/process/process?id=exec)接口,创建的进程可以执行其他程序,与原`PHP`父进程之间可以方便的通信
-* 在协程环境中无法使用`Process`模块,可以使用`runtime hook`+`proc_open`实现,参考[协程进程管理](/coroutine/proc_open)
+* 不能在协程中使用`Process`模块,参考[协程中创建进程](/coroutine/notice?id=协程中创建进程)
### 使用示例
@@ -44,44 +44,44 @@ echo 'Parent #' . getmypid() . ' exit' . PHP_EOL;
## 属性
-### pipe
+### id
-[unixSocket](/learn?id=什么是IPC)的文件描述符。
+当前进程`id`。
```php
-public int $pipe;
+public int $id;
```
-### msgQueueId
+### pid
-消息队列的`id`。
+当前进程的进程`pid`。
```php
-public int $msgQueueId;
+public int $pid;
```
-### msgQueueKey
+### pipe
-消息队列的`key`。
+[unixSocket](/learn?id=什么是IPC)的文件描述符。
```php
-public string $msgQueueKey;
+public int $pipe;
```
-### pid
+### msgQueueId
-当前进程的`pid`。
+消息队列的`id`。
```php
-public int $pid;
+public int $msgQueueId;
```
-### id
+### msgQueueKey
-当前进程`id`。
+消息队列的`key`。
```php
-public int $id;
+public string $msgQueueKey;
```
## 常量
@@ -119,7 +119,7 @@ Swoole\Process->__construct(callable $function, bool $redirect_stdin_stdout = fa
* **其它值**:`0`、`SOCK_STREAM`
* **`bool $enable_coroutine`**
- * **功能**:在`callback function`中启用协程,开启后可以直接在子进程的函数中使用协程API
+ * **功能**:在`callback function`中启用协程,开启后可以直接在子进程的函数中使用协程API或者开启[一键协程化](/runtime),避免阻塞函数阻塞进程。
* **默认值**:`false`
* **其它值**:`true`
* **版本影响**:Swoole版本 >= v4.3.0
@@ -266,7 +266,7 @@ Swoole\Process->setTimeout(float $seconds): bool
设置消息队列套接字是否阻塞。
```php
-Swoole\Process->setBlocking(bool $$blocking): void
+Swoole\Process->setBlocking(bool $blocking): void
```
* **参数**
diff --git a/public/zh-cn/server/methods.md b/public/zh-cn/server/methods.md
index 0a1d3ec..339eb6d 100644
--- a/public/zh-cn/server/methods.md
+++ b/public/zh-cn/server/methods.md
@@ -220,6 +220,7 @@ Swoole\Server->addProcess(Swoole\Process $process): int
-用户进程内不能使用`Server->task/taskwait`接口。
-用户进程内可以使用`Server->send/close`等接口。
-用户进程内应当进行`while(true)`(如下边的示例)或[EventLoop](/learn?id=什么是eventloop)循环(例如创建个定时器),否则用户进程会不停地退出重启。
+ -必须在`Server->start()`执行之前使用`addProcess`,否则用户进程不会启动的。
* **生命周期**
diff --git a/public/zh-cn/server/setting.md b/public/zh-cn/server/setting.md
index 7856fa7..e917b60 100644
--- a/public/zh-cn/server/setting.md
+++ b/public/zh-cn/server/setting.md
@@ -166,40 +166,6 @@ $server->set([
]);
```
-### hook_flags
-
-?> **设置`一键协程化`Hook的函数范围。**【默认值:不hook】
-
-!> Swoole版本为 `v4.5+` 或 [4.4LTS](https://github.com/swoole/swoole-src/tree/v4.4.x) 可用,详情参考[一键协程化](/runtime)
-
-```php
-$server->set([
- 'hook_flags' => SWOOLE_HOOK_SLEEP,
-]);
-```
-底层支持以下协程化项,可使用`SWOOLE_HOOK_ALL`表示协程化全部:
-
-* `SWOOLE_HOOK_TCP`
-* `SWOOLE_HOOK_UNIX`
-* `SWOOLE_HOOK_UDP`
-* `SWOOLE_HOOK_UDG`
-* `SWOOLE_HOOK_SSL`
-* `SWOOLE_HOOK_TLS`
-* `SWOOLE_HOOK_SLEEP`
-* `SWOOLE_HOOK_FILE`
-* `SWOOLE_HOOK_STREAM_FUNCTION`
-* `SWOOLE_HOOK_BLOCKING_FUNCTION`
-* `SWOOLE_HOOK_PROC`
-* `SWOOLE_HOOK_CURL`
-* `SWOOLE_HOOK_NATIVE_CURL`
-* `SWOOLE_HOOK_SOCKETS`
-* `SWOOLE_HOOK_STDIO`
-* `SWOOLE_HOOK_PDO_PGSQL`
-* `SWOOLE_HOOK_PDO_ODBC`
-* `SWOOLE_HOOK_PDO_ORACLE`
-* `SWOOLE_HOOK_PDO_SQLITE`
-* `SWOOLE_HOOK_ALL`
-
### enable_preemptive_scheduler
?> 设置打开协程抢占式调度,避免其中一个协程执行时间过长导致其他协程饿死,协程最大执行时间为`10ms`。
@@ -230,6 +196,31 @@ $server->set([
?> 工作线程最大空闲时间,单位为秒。
+### iouring_entries
+
+?> 设置`io_uring`的队列大小,默认为`8192`,如果传入的值不是`2的次方数`,内核会修改为最接近的,大于该值的`2的次方数`。
+
+!> 如果传入的值过大,内核会抛出异常并且终止程序。
+
+!> 当系统安装了`liburing`和编译`Swoole`开启了`--enable-iouring`之后才能使用。
+
+### iouring_workers
+
+?> 设置`io_uring`的工作线程数,默认值是`CPU 核数 * 4`。
+
+!> 如果传入的值过大,内核会抛出异常并且终止程序。
+
+!> 当系统安装了`liburing`和编译`Swoole`开启了`--enable-iouring`之后才能使用。
+
+### iouring_flag
+
+?> 设置`io_uring`的工作模式,默认值为`SWOOLE_IOURING_DEFAULT`。
+
+- `SWOOLE_IOURING_DEFAULT`,中断驱动模式,可通过系统调用`io_uring_enter`提交`I/O`请求,然后直接检查完成队列状态判断是否完成。
+- `SWOOLE_IOURING_SQPOLL`,内核轮询模式,内核会创建内核线程用于提交和收割`I/O`请求,几乎完全消除用户态内核态上下文切换,性能较好。
+
+!> 如果传入的模式不正确,内核会统一使用`SWOOLE_IOURING_DEFAULT`中断驱动模式。
+
### reactor_num
?> **设置启动的 [Reactor](/learn?id=reactor线程) 线程数。**【默认值:`CPU`核数】
@@ -1526,7 +1517,7 @@ $server->set([
* 当`enable_coroutine`设置为`true`时,底层自动在[onRequest](/http_server?id=on)回调中创建协程,开发者无需自行使用`go`函数[创建协程](/coroutine/coroutine?id=create)
* 当`enable_coroutine`设置为`false`时,底层不会自动创建协程,开发者如果要使用协程,必须使用`go`自行创建协程,如果不需要使用协程特性,则处理方式与`Swoole1.x`是100%一致的
-* 注意,这个开启只是说明Swoole会通过协程去处理请求,如果事件中含有阻塞函数,那需要提前开启[一键协程化](/runtime),将`sleep`,`mysqlnd`这些阻塞的函数或者扩展开启协程化
+* 注意,这个开启只是说明Swoole会通过协程去处理请求,如果事件中含有阻塞函数,那需要提前配置`hook_flags`或者开启[一键协程化](/runtime),将`sleep`,`mysqlnd`这些阻塞的函数或者扩展开启协程化
```php
$server = new Swoole\Http\Server("127.0.0.1", 9501);
@@ -1552,6 +1543,40 @@ $server->on("request", function ($request, $response) {
$server->start();
```
+### hook_flags
+
+?> **设置`一键协程化`Hook的函数范围。**【默认值:不hook】
+
+!> Swoole版本为 `v4.5+` 或 [4.4LTS](https://github.com/swoole/swoole-src/tree/v4.4.x) 可用,详情参考[一键协程化](/runtime)
+
+```php
+$server->set([
+ 'hook_flags' => SWOOLE_HOOK_SLEEP,
+]);
+```
+底层支持以下协程化项,可使用`SWOOLE_HOOK_ALL`表示协程化全部:
+
+* `SWOOLE_HOOK_TCP`
+* `SWOOLE_HOOK_UNIX`
+* `SWOOLE_HOOK_UDP`
+* `SWOOLE_HOOK_UDG`
+* `SWOOLE_HOOK_SSL`
+* `SWOOLE_HOOK_TLS`
+* `SWOOLE_HOOK_SLEEP`
+* `SWOOLE_HOOK_FILE`
+* `SWOOLE_HOOK_STREAM_FUNCTION`
+* `SWOOLE_HOOK_BLOCKING_FUNCTION`
+* `SWOOLE_HOOK_PROC`
+* `SWOOLE_HOOK_CURL`
+* `SWOOLE_HOOK_NATIVE_CURL`
+* `SWOOLE_HOOK_SOCKETS`
+* `SWOOLE_HOOK_STDIO`
+* `SWOOLE_HOOK_PDO_PGSQL`
+* `SWOOLE_HOOK_PDO_ODBC`
+* `SWOOLE_HOOK_PDO_ORACLE`
+* `SWOOLE_HOOK_PDO_SQLITE`
+* `SWOOLE_HOOK_ALL`
+
### send_yield
?> **当发送数据时缓冲区内存不足时,直接在当前协程内[yield](/coroutine?id=协程调度),等待数据发送完成,缓存区清空时,自动[resume](/coroutine?id=协程调度)当前协程,继续`send`数据。**【默认值:在[dispatch_mod](/server/setting?id=dispatch_mode) 2/4时候可用,并默认开启】
diff --git a/public/zh-cn/thread/arraylist.md b/public/zh-cn/thread/arraylist.md
index 17be801..b8b714e 100644
--- a/public/zh-cn/thread/arraylist.md
+++ b/public/zh-cn/thread/arraylist.md
@@ -127,3 +127,18 @@ Swoole\Thread\ArrayList()->toArray(): array
```php
Swoole\Thread\ArrayList()->clean(): void
```
+
+### find()
+根据值搜索`ArrayList`中对应的数字key。
+
+```php
+Swoole\Thread\ArrayList()->find(mixed $value): int
+```
+* **参数**
+ * `mixed $value`
+ * 功能:需要搜索的值。
+ * 默认值:无。
+ * 其它值:无。
+
+* **返回值**
+ * 返回该值对应的索引。
diff --git a/public/zh-cn/thread/barrier.md b/public/zh-cn/thread/barrier.md
index 7fe7255..af9345b 100644
--- a/public/zh-cn/thread/barrier.md
+++ b/public/zh-cn/thread/barrier.md
@@ -1,11 +1,14 @@
-# 线程同步执行屏障 Barrier
+# 同步执行屏障 Barrier
+
+## 线程同步屏障
`Thread\Barrier` 是一种线程同步的机制。它允许多个线程在特定的点上进行同步,确保所有线程在某个临界点(障碍)之前都完成了自己的任务。只有当所有参与的线程都到达这个障碍时,它们才能继续执行后续的代码。
例如我们创建了`4`个线程,希望这些线程全部就绪后一起执行任务,就像跑步比赛中裁判的发令枪,在发出信号之后同时起跑。这就可以用`Thread\Barrier`实现。
+!> 该线程同步屏障会导致线程挂起,因此不能用于多协程同步。
-## 示例
+### 示例
```php
use Swoole\Thread;
use Swoole\Thread\Barrier;
@@ -29,9 +32,9 @@ if (empty($args)) {
}
```
-## 方法
+### 方法
-### __construct()
+#### __construct()
构造方法
```php
@@ -46,10 +49,84 @@ Thread\Barrier()->__construct(int $count): void
执行`wait`操作的线程数量必须与设置的计数一致,否则所有线程均会阻塞。
-### wait()
+#### wait()
阻塞等待其他线程,直到所有线程均处于`wait`状态时,会同时唤醒所有等待的线程,继续向下执行。
```php
Thread\Barrier()->wait(): void
```
+
+## 协程同步屏障
+
+在 [Swoole Library](https://github.com/swoole/library) 中底层提供了一个更便捷的协程并发管理工具:`Coroutine\Barrier` 协程屏障,或者叫协程栅栏。基于 `PHP` 引用计数和 `Coroutine API` 实现。
+
+相比于[Coroutine\WaitGroup](/coroutine/wait_group),`Coroutine\Barrier`使用更简单一些,只需通过参数传递或者闭包的`use`语法,引入子协程函数上即可。
+
+!> Swoole 版本 >= v4.5.5 时可用。
+
+!> 该协程屏障只能用于单进程或者单线程中的多协程同步,主要作用还是让主协程等待全部子协程完成任务后退出。
+
+### 使用示例
+
+```php
+use Swoole\Coroutine\Barrier;
+use Swoole\Coroutine\System;
+use function Swoole\Coroutine\run;
+use Swoole\Coroutine;
+
+run(function () {
+ $barrier = Barrier::make();
+
+ $count = 0;
+ $N = 4;
+
+ foreach (range(1, $N) as $i) {
+ Coroutine::create(function () use ($barrier, &$count) {
+ System::sleep(0.5);
+ $count++;
+ });
+ }
+
+ Barrier::wait($barrier);
+
+ assert($count == $N);
+});
+```
+
+### 方法
+
+#### make()
+生成一个协程屏障。
+
+```php
+Coroutine\Barrier::make(): self
+```
+
+#### wait()
+等待所有协程就绪
+
+```php
+Coroutine\Barrier::wait(Barrier &$barrier, float $timeout = -1): void
+```
+
+* **参数**
+ * `int $barrier`
+ * 功能:由`Coroutine\Barrier::make()`返回的协程屏障。
+ * 默认值:无。
+ * 其它值:无。
+ * `float $timeout`
+ * 功能:超时时间。
+ * 默认值:-1,表示永不超时。
+ * 其它值:无。
+
+### 执行流程
+
+* 先使用`Barrier::make()`创建了一个新的协程屏障
+* 在子协程用使用`use`语法传递屏障,增加引用计数
+* 在需要等待的位置加入`Barrier::wait($barrier)`,这时会自动挂起当前协程,等待引用该协程屏障的子协程退出
+* 子协程退出时会减少`$barrier`对象的引用计数,直到为`0`
+* 当所有子协程完成了任务处理并退出时,`$barrier`对象引用计数为`0`,在`$barrier`对象析构函数中底层会自动恢复挂起的协程,从`Barrier::wait($barrier)`函数中返回
+
+`Coroutine\Barrier` 是一个比 [WaitGroup](/coroutine/wait_group) 和 [Channel](/coroutine/channel) 更易用的并发控制器,大幅提升了 `PHP` 并发编程的用户体验。
+
diff --git a/public/zh-cn/thread/info.md b/public/zh-cn/thread/info.md
index 9abb25f..f406287 100644
--- a/public/zh-cn/thread/info.md
+++ b/public/zh-cn/thread/info.md
@@ -1,5 +1,32 @@
# 方法与属性
+## 属性
+
+### id
+
+通过此对象属性获取子线程的 `ID`,该属性是`int`类型。
+
+> 此属性仅用在父线程,子线程无法获得`$thread`对象,应使用`Thread::getId()`静态方法获取线程的`ID`
+
+```php
+$thread = new Swoole\Thread(__FILE__, $i);
+var_dump($thread->id);
+```
+
+## 常量
+
+名称 | 作用
+---|---
+`Thread::HARDWARE_CONCURRENCY` | 硬件并发线程数量,一般为`CPU`核数
+`Thread::API_NAME` | 线程 `API` 名称,例如 `POSIX Threads`
+`Thread::SCHED_OTHER` | 线程调度策略 `SCHED_OTHER`
+`Thread::SCHED_FIFO` | 线程调度策略 `SCHED_FIFO`
+`Thread::SCHED_RR` | 线程调度策略 `SCHED_RR`
+`Thread::SCHED_BATCH` | 线程调度策略 `SCHED_BATCH`
+`Thread::SCHED_ISO` | 线程调度策略 `SCHED_ISO`
+`Thread::SCHED_IDLE` | 线程调度策略 `SCHED_IDLE`
+`Thread::SCHED_DEADLINE` | 线程调度策略 `SCHED_DEADLINE`
+
## 方法
### __construct()
@@ -178,16 +205,16 @@ Swoole\Thread->setName(string $name): bool
* 失败返回`false`,使用`swoole_last_error()`获取错误信息
```shell
-$ ps aux|grep -v grep|grep pool.php
-swoole 2226813 0.1 0.1 423860 49024 pts/6 Sl+ 17:38 0:00 php pool.php
+$ ps aux|grep -v grep|grep pool.php
+swoole 2226813 0.1 0.1 423860 49024 pts/6 Sl+ 17:38 0:00 php pool.php
-$ ps -T -p 2226813
- PID SPID TTY TIME CMD
-2226813 2226813 pts/6 00:00:00 Master Thread
-2226813 2226814 pts/6 00:00:00 Worker Thread 0
-2226813 2226815 pts/6 00:00:00 Worker Thread 1
-2226813 2226816 pts/6 00:00:00 Worker Thread 2
-2226813 2226817 pts/6 00:00:00 Worker Thread 3
+$ ps -T -p 2226813
+ PID SPID TTY TIME CMD
+2226813 2226813 pts/6 00:00:00 Master Thread
+2226813 2226814 pts/6 00:00:00 Worker Thread 0
+2226813 2226815 pts/6 00:00:00 Worker Thread 1
+2226813 2226816 pts/6 00:00:00 Worker Thread 2
+2226813 2226817 pts/6 00:00:00 Worker Thread 3
```
### getNativeId()
@@ -200,31 +227,3 @@ Swoole\Thread->getNativeId(): int
此函数在`Linux`系统会调用`gettid()`系统调用,获取一个类似于操作系统线程`ID`,是一个短整数。当进程线程销毁时可能会被操作系统服用。
此`ID`可以用于`gdb`、`strace`调试,例如`gdb -p $tid`。另外还可以读取`/proc/{PID}/task/{ThreadNativeId}`获取线程的执行信息。
-
-## 属性
-
-### id
-
-通过此对象属性获取子线程的 `ID`,该属性是`int`类型。
-
-> 此属性仅用在父线程,子线程无法获得`$thread`对象,应使用`Thread::getId()`静态方法获取线程的`ID`
-
-```php
-$thread = new Swoole\Thread(__FILE__, $i);
-var_dump($thread->id);
-```
-
-## 常量
-
-名称 | 作用
----|---
-`Thread::HARDWARE_CONCURRENCY` | 硬件并发线程数量,一般为`CPU`核数
-`Thread::API_NAME` | 线程 `API` 名称,例如 `POSIX Threads`
-`Thread::SCHED_OTHER` | 线程调度策略 `SCHED_OTHER`
-`Thread::SCHED_FIFO` | 线程调度策略 `SCHED_FIFO`
-`Thread::SCHED_RR` | 线程调度策略 `SCHED_RR`
-`Thread::SCHED_BATCH` | 线程调度策略 `SCHED_BATCH`
-`Thread::SCHED_ISO` | 线程调度策略 `SCHED_ISO`
-`Thread::SCHED_IDLE` | 线程调度策略 `SCHED_IDLE`
-`Thread::SCHED_DEADLINE` | 线程调度策略 `SCHED_DEADLINE`
-
diff --git a/public/zh-cn/thread/map.md b/public/zh-cn/thread/map.md
index cc9056a..ea09301 100644
--- a/public/zh-cn/thread/map.md
+++ b/public/zh-cn/thread/map.md
@@ -174,3 +174,18 @@ Swoole\Thread\Map()->toArray(): array
```php
Swoole\Thread\Map()->clean(): void
```
+
+### find()
+根据值搜索`Map`中对应的key。
+
+```php
+Swoole\Thread\Map()->find(mixed $value): mixed
+```
+* **参数**
+ * `mixed $value`
+ * 功能:需要搜索的值。
+ * 默认值:无。
+ * 其它值:无。
+
+* **返回值**
+ * 返回该值对应的key。
diff --git a/public/zh-cn/thread/thread.md b/public/zh-cn/thread/thread.md
index 5165133..b3dffd9 100644
--- a/public/zh-cn/thread/thread.md
+++ b/public/zh-cn/thread/thread.md
@@ -3,36 +3,36 @@
从 `6.0` 版本开始提供了多线程支持,可使用线程 `API` 来代替多进程。相比多进程,`Thread` 提供了更丰富的并发数据容器,
在开发游戏服务器、通信服务器方面更方便。
-- `PHP` 必须为 `ZTS` 模式,编译 `PHP` 时需要加入 `--enable-zts`
-- 编译 `Swoole` 时需要增加 `--enable-swoole-thread` 编译选项
+- `PHP` 必须为 `ZTS` 模式,编译 `PHP` 时需要加入 `--enable-zts`。
+- 编译 `Swoole` 时需要增加 `--enable-swoole-thread` 编译选项。
## 资源隔离
`Swoole` 线程与 `Node.js Worker Thread` 是相似的,在子线程中会创建一个全新的 `ZendVM` 环境。 子线程不会从父线程继承任何资源,因此在子线程中下列内容已被清空,需要重新创建或设置。
-- 已加载的 `PHP` 文件,需要重新 `include/require` 加载
-- 需要重新注册`autoload` 函数
-- 类、函数、常量,将被清空,需重新加载 `PHP` 文件创建
-- 全局变量,例如 `$GLOBALS`、`$_GET/$_POST` 等,将被重置
-- 类的静态属性、函数的静态变量,将重置为初始值
-- 一些`php.ini` 选项,例如 `error_reporting()` 需要在子线程中重新设置
+- 已加载的 `PHP` 文件,需要重新 `include/require` 加载。
+- 需要重新注册`autoload` 函数。
+- 类、函数、常量,将被清空,需重新加载 `PHP` 文件创建。
+- 全局变量,例如 `$GLOBALS`、`$_GET/$_POST` 等,将被重置。
+- 类的静态属性、函数的静态变量,将重置为初始值。
+- 一些`php.ini` 选项,例如 `error_reporting()` 需要在子线程中重新设置。
## 不可用特性
-在多线程模式下,下列特性仅支持在主线程中操作,无法在子线程中执行:
+在多线程模式下,下列特性仅支持在主线程中操作,主线程的设置会影响到子线程:
-- `swoole_async_set()` 修改线程参数
-- `Swoole\Runtime::enableCoroutine()` 和 `Swoole\Runtime::setHookFlags()`
-- 仅主线程可设置信号监听,包括 `Process::signal()` 和 `Coroutine\System::waitSignal()` 不能在子线程中使用
-- 仅主线程可创建异步服务器,包括 `Server`、`Http\Server`、`WebSocket\Server` 等不能在子线程中使用
+- 只能由主线程通过`swoole_async_set()` 设置线程参数
+- 只能由主线程通过`Swoole\Runtime::enableCoroutine()` 和 `Swoole\Runtime::setHookFlags()`设置协程参数。
+- 仅主线程可设置信号监听,包括 `Process::signal()` 和 `Coroutine\System::waitSignal()` 不能在子线程中设置。
+- 仅主线程可创建异步服务器,包括 `Server`、`Http\Server`、`WebSocket\Server` 等不能在子线程中使用。
-除此之外,`Runtime Hook` 在多线程模式下开启后将无法关闭。
-## 致命错误
-当主线程退出时,若依然存在活跃的子线程,将抛出一个致命错误,退出的状态码为:`200`,错误信息如下:
-```
-Fatal Error: 2 active threads are running, cannot exit safely.
-```
+
+## 注意
+!> 除此之外,`Runtime Hook` 在多线程模式下开启后将无法关闭。
+
+!> 当主线程退出时,若依然存在活跃的子线程,将抛出一个致命错误,退出的状态码为:`200`,错误信息如下:
+`Fatal Error: 2 active threads are running, cannot exit safely`
## 查看是否开启线程支持
@@ -43,7 +43,7 @@ Copyright (c) The PHP Group
Zend Engine v4.1.23, Copyright (c) Zend Technologies
```
-`(ZTS)` 表示已启用线程安全
+`(ZTS)` 表示已启用线程安全。
```shell
php --ri swoole
@@ -53,7 +53,7 @@ Swoole => enabled
thread => enabled
```
-`thread => enabled` 表示已开启多线程支持
+`thread => enabled` 表示已开启多线程支持。
### 创建多线程
```php
@@ -82,11 +82,11 @@ if (empty($args)) {
```
### 线程 + 服务端(异步风格)
-- 所有工作进程将使用线程来运行,包括 `Worker`、`Task Worker`、`User Process`
-- 新增 `SWOOLE_THREAD` 运行模式,启用后将使用线程代替进程运行
-- 增加了 [bootstrap](/server/setting?id=bootstrap) 和 [init_arguments](/server/setting?id=init_arguments) 两项配置,用于设置工作线程的入口脚本文件、线程共享数据
-- 必须在主线程中创建 `Server`,可在回调函数中创建新的 `Thread` 执行其他任务
-- `Server::addProcess()` 进程对象不支持标准输入输出重定向
+- 所有工作进程将使用线程来运行,包括 `Worker`、`Task Worker`、`User Process`。
+- 新增 `SWOOLE_THREAD` 运行模式,启用后将使用线程代替进程运行。
+- 增加了 [bootstrap](/server/setting?id=bootstrap) 和 [init_arguments](/server/setting?id=init_arguments) 两项配置,用于设置工作线程的入口脚本文件、线程共享数据。
+- 必须在主线程中创建 `Server`,可在回调函数中创建新的 `Thread` 执行其他任务。
+- `Server::addProcess()` 进程对象不支持标准输入输出重定向。
```php
use Swoole\Process;
diff --git a/public/zh-cn/version/log.md b/public/zh-cn/version/log.md
index 6e50aed..bfbde5f 100644
--- a/public/zh-cn/version/log.md
+++ b/public/zh-cn/version/log.md
@@ -8,6 +8,7 @@
* 8.1
* 8.2
* 8.3
+* 8.4
## 建议使用的Swoole版本
`Swoole6.x`和`Swoole5.x`
@@ -31,6 +32,184 @@ php --ri swoole
## v6.0.0
+### 新特性:
+- `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
+- 新增`Swoole\Thread\Map::find()`方法。 @matyhtf
+- 新增`Swoole\Thread\ArrayList::find()`方法。 @matyhtf
+- 新增`Swoole\Thread\ArrayList::offsetUnset()`方法。 @matyhtf
+- 新增`Swoole\Process::getAffinity()`方法。 @matyhtf
+- 新增`Swoole\Thread::setName()`方法。 @matyhtf
+- 新增`Swoole\Thread::setAffinity()`方法。 @matyhtf
+- 新增`Swoole\Thread::getAffinity()`方法。 @matyhtf
+- 新增`Swoole\Thread::setPriority()`方法。 @matyhtf
+- 新增`Swoole\Thread::getPriority()`方法。 @matyhtf
+- 新增`Swoole\Thread::gettid()`方法。
+- 文件异步引擎`iouring`支持多线程轮询模式`IORING_SETUP_SQPOLL`。 @NathanFreeman
+- 新增`iouring_workers`修改`iouring`线程数。 @NathanFreeman
+- 新增`iouring_flags`支持修改`iouring`工作模式。 @NathanFreeman
+- 增加`Swoole\Thead\Barrier`多线程同步屏障。@matyhtf
+- 增加新的设置cookie的函数。 @matyhtf @NathanFreeman
+- 新增`非阻塞,可重入的互斥协程锁”,该锁可以在进程间/线程间使用,且不会阻塞进程/线程。 @NathanFreeman
+- `Swoole\Coroutine\Socket::getOption()`支持了`TCP_INFO`选项。 @matyhtf
+- `Swoole\Client`同步阻塞客户端支持`http`代理。 @matyhtf
+- 新增异步非阻塞的`TCP/UDP/Unixsocket` 客户端`Swoole\Async\Client`。 @matyhtf
+- 优化`Swoole\Redis\Server::format`()方法,支持内存零拷贝,支持`redis`嵌套结构。 @matyhtf
+- 支持高性能压缩工具`Zstd`,只需要在编译`Swoole`时加上`--enable-zstd`,`http`客户端和服务端之间便可使用`zstd`来压缩响应或者解码响应。 @NathanFreeman
+
+### 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
+- 修复`Swoole\Http2\Request`动态属性问题。 @guandeng
+- 修复`pgsql`协程客户端偶发资源不可用的问题。 @NathanFreeman
+- 修复进程重启,没有重置相关参数导致503错误的问题。@matyhtf
+- 修复开启`HTTP2`时,`$request->server['request_method']` 与 `$request->getMethod()` 的结果不一致。 @matyhtf
+- 修复上传文件时,不正确的`content-type`。 @matyhtf
+- 修复`http2`协程客户端的代码错误。 @matyhtf
+- 修复`Swoole\Server`缺少属性`worker_id`的问题。 @cjavad
+- 修复`config.m4`有关`brotli`错误的问题。 @fundawang
+- 修复 多线程下`Swoole\Http\Response::create`无效。 @matyhtf
+- 修复`macos`环境下编译错误。 @matyhtf
+- 修复线程无法安全退出的问题。 @matyhtf
+- 修复多线程模式下,`Swoole\Http\Response`返回响应时间的静态变量没有各个线程各自生成一份的问题。 @matyhtf @NathanFreeman
+- 修复因为`PHP-8.4`在ZTS模式下的`超时`特性引起的`Fatal error`问题。 @matyhtf
+- 修复`PHP-8.4`的`exit()`函数`hook`。 @remicollet
+- 修复`Swoole\Thread::getNativeId()`在`cygwin`无法工作的问题。 @matyhtf
+- 修复`Swoole\Coroutine::getaddrinfo()`方法会导致`SIGSEGV`的问题。 @matyhtf
+- 修复`runtime tcp`模块不支持动态开启SSL加密的问题。 @matyhtf
+- 修复http客户端长时间运行导致超时时间不正确的问题。 @matyhtf
+- 修复进程退出之前会导致`Swoole\Table`的互斥锁无法使用的问题。 @matyhtf
+- 修复使用命名参数导致`Swoole\Server::stop()`执行失败的问题。 @matyhtf
+- 修复`Swoole\Thread\Map::toArray()`函数未复制`key`导致崩溃的问题。 @matyhtf
+- 修复`Swoole\Thread\Map`无法删除嵌套的数字键的问题。 @matyhtf
+
+### 内核优化:
+- 移除对`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
+- 升级CI测试的oracle数据库版本。 @gvenzl
+- 优化底层`sendfile`的相关逻辑。 @matyhtf
+- `config.m4`中用`AC_DEFINE_UNQUOTED`替换`PHP_DEF_HAVE`。 @petk
+- 优化多线程模式下,server的`heartbeat`,`shutdown`和`stop`的相关逻辑。 @matyhtf
+- 优化`glibc`版本高于2.17时,不需要链接`librt`。 @matyhtf
+- 加强`http`客户端可以接受重复的请求头。 @matyhtf
+- 优化`Swoole\Http\Response::write()`。 @matyhtf
+- `Swoole\Http\Response::write()`现在可以发送`http2`协议。 @matyhtf
+- 兼容`PHP8.4`。 @matyhtf @NathanFreeman
+- 增加底层`socket`异步写入的能力。 @matyhtf
+- 优化`Swoole\Http\Response`。 @NathanFreeman
+- 多线程模式下,支持共享php原生`socket`。 @matyhtf
+- 优化静态文件服务,修复静态文件路径错误问题。 @matyhtf
+- 异步`Server`多线程模式支持重启工作线程。 @matyhtf
+- 异步`Server`多线程模式支持在`Manager`线程中开启定时器。 @matyhtf
+- 兼容`PHP-8.4`的`curl`扩展。 @matyhtf @NathanFreeman
+- 重新封装`Swoole`底层使用`iouring`的代码。 @matyhtf @NathanFreeman
+- 优化定时器,使同步进程不依赖于信号。 @matyhtf
+- 优化`Swoole\Coroutine\System::waitSignal()`方法,允许同时监听多个信号。 @matyhtf
+
+### 废弃:
+- 不再支持`PHP 8.0`。
+- 不再支持`Swoole\Coroutine\MySQL`协程客户端。
+- 不再支持`Swoole\Coroutine\Redis`协程客户端。
+- 不再支持`Swoole\Coroutine\PostgreSQL`协程客户端。
+- 移除`Swoole\Coroutine\System::fread()`, `Swoole\Coroutine\System::fwrite()`和`Swoole\Coroutine\System::fgets()`方法
+
+## v5.1.5
+
+### Bug修复:
+- 修复php版本大于8.2,需要使用`zend_ini_parse_quantity`解析字符串数字。 @matyhtf
+- 修复`pdo_pgsql`协程化的时候,偶发资源不可用的问题。 @NathanFreeman
+- 修复`pdo_pgsql`协程化的时候,头文件引用问题。 @NathanFreeman
+- 修复不正确的相对路径检查,以避免绕过路径验证。 @matyhtf
+- 修复高并发环境下,进程重启会导致并发数不正确。 @matyhtf
+
+### 内核优化:
+- 同步`php8.3 curl`的一些相关代码。 @NathanFreeman
+- 修复`process`模块核心测试错误。 @NathanFreeman
+- 在`SWOOLE_BASE`模式下,所有的连接都应该在`PHP RSHUTDOWN`阶段都被关闭。 @matyhtf
+- 优化内核代码。 @matyhtf
+
+## v6.0.0-beta
+
+### 新特性:
+- 新增`Swoole\Thread\Map::find()`方法。 @matyhtf
+- 新增`Swoole\Thread\ArrayList::find()`方法。 @matyhtf
+- 新增`Swoole\Thread\ArrayList::offsetUnset()`方法。 @matyhtf
+- 新增`Swoole\Process::getAffinity()`方法。 @matyhtf
+- 新增`Swoole\Thread::setName()`方法。 @matyhtf
+- 新增`Swoole\Thread::setAffinity()`方法。 @matyhtf
+- 新增`Swoole\Thread::getAffinity()`方法。 @matyhtf
+- 新增`Swoole\Thread::setPriority()`方法。 @matyhtf
+- 新增`Swoole\Thread::getPriority()`方法。 @matyhtf
+- 新增`Swoole\Thread::gettid()`方法。
+- 文件异步引擎`iouring`支持多线程轮询模式`IORING_SETUP_SQPOLL`。 @NathanFreeman
+- 新增`iouring_workers`修改`iouring`线程数。 @NathanFreeman
+- 新增`iouring_flags`支持修改`iouring`工作模式。 @NathanFreeman
+- 增加`Swoole\Thead\Barrier`多线程同步屏障。@matyhtf
+- 增加新的设置cookie的函数。 @matyhtf @NathanFreeman
+
+### Bug修复:
+- 修复`Swoole\Http2\Request`动态属性问题。 @guandeng
+- 修复`pgsql`协程客户端偶发资源不可用的问题。 @NathanFreeman
+- 修复进程重启,没有重置相关参数导致503错误的问题。@matyhtf
+- 修复开启`HTTP2`时,$request->server['request_method'] 与 $request->getMethod() 的结果不一致。 @matyhtf
+- 修复上传文件时,不正确的`content-type`。 @matyhtf
+- 修复`http2`协程客户端的代码错误。 @matyhtf
+- 修复`Swoole\Server`缺少属性`worker_id`的问题。 @cjavad
+- 修复`config.m4`有关`brotli`错误的问题。 @fundawang
+- 修复 多线程下`Swoole\Http\Response::create`无效。 @matyhtf
+- 修复`macos`环境下编译错误。 @matyhtf
+- 修复线程无法安全退出的问题。 @matyhtf
+- 修复多线程模式下,`Swoole\Http\Response`返回响应时间的静态变量没有各个线程各自生成一份的问题。 @matyhtf @NathanFreeman
+
+### 内核优化:
+- 升级CI测试的oracle数据库版本。 @gvenzl
+- 重构优化`swoole`底层相关代码。 @matyhtf
+- 优化底层`sendfile`的相关逻辑。 @matyhtf
+- 优化参数解析。 @matyhtf
+- `config.m4`中用`AC_DEFINE_UNQUOTED`替换`PHP_DEF_HAVE`。 @petk
+- 优化多线程模式下,server的`heartbeat`,`shutdown`和`stop`的相关逻辑。 @matyhtf
+- 优化`glibc`版本高于2.17时,不需要链接`librt`。 @matyhtf
+- 加强`http`客户端可以接受重复的请求头。 @matyhtf
+- 优化`Swoole\Http\Response::write()`。 @matyhtf
+- `Swoole\Http\Response::write()`现在可以发送`http2`协议。 @matyhtf
+- 兼容`PHP8.4`。 @matyhtf @NathanFreeman
+- 增加底层`socket`异步写入的能力。 @matyhtf
+- 优化`Swoole\Http\Response`。 @NathanFreeman
+- 优化底层错误信息。 @matyhtf
+- 多线程模式下,支持共享php原生`socket`。 @matyhtf
+- 优化静态文件服务,修复静态文件路径错误问题。 @matyhtf
+
+### 废弃:
+- 移除`Swoole\Coroutine\System::fread()`, `Swoole\Coroutine\System::fwrite()`和`Swoole\Coroutine\System::fgets()`方法
+
+## v6.0.0-alpha
+
### 新特性
- `Swoole`支持多线程模式,当`php`是`zts`模式,编译`Swoole`时开启`--enable-swoole-thread`时,就能使用多线程模式。
- 新增线程管理类`Swoole\Thread`。 @matyhtf