Skip to content
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

Translate some documents #398

Merged
merged 1 commit into from
Mar 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions README_ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/acl-dev/open-coroutine.svg)](http://isitmaintained.com/project/acl-dev/open-coroutine "解决issue的平均时间")
[![Percentage of issues still open](http://isitmaintained.com/badge/open/acl-dev/open-coroutine.svg)](http://isitmaintained.com/project/acl-dev/open-coroutine "仍未关闭issue的百分比")

`open-coroutine`是一个简单、高效、通用的有栈协程库,您可以将其用作IO线程池的性能替代,查看[为什么更好](core/docs/en/why-better.md).
`open-coroutine`是一个简单、高效、通用的有栈协程库,您可以将其用作IO线程池的性能替代,查看[为什么更好](core/docs/cn/why-better.md).

[English](README.md) | 中文

Expand All @@ -31,7 +31,7 @@
- [ ]
增加性能[基准测试](https://github.com/TechEmpower/FrameworkBenchmarks/wiki/Project-Information-Framework-Tests-Overview);
- [ ] 取消协程/任务;
- [ ] 增加性能指标;
- [ ] 增加性能指标监控;
- [ ] 增加并发工具包;
- [ ] 支持AF_XDP套接字;

Expand Down Expand Up @@ -181,8 +181,16 @@ fn main() {

## ⚓ 了解更多

- [项目总览](core/docs/cn/overview.md)
- [诞生之因](docs/cn/background.md)
- [语言选择](docs/cn/why-rust.md)
- [协程总览](core/docs/cn/coroutine.md)
- [可伸缩栈总览](core/docs/cn/scalable-stack.md)
- [Monitor总览](core/docs/cn/monitor.md)
- [工作窃取总览](core/docs/cn/work-steal.md)
- [有序工作窃取总览](core/docs/cn/ordered-work-steal.md)
- [协程池总览](core/docs/cn/coroutine-pool.md)
- [Hook总览](hook/docs/cn/hook.md)

[旧版文档在这](https://github.com/acl-dev/open-coroutine-docs)

Expand Down
1 change: 0 additions & 1 deletion core/docs/cn/coroutine-pool.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ sequenceDiagram
participant WorkerCoroutine
participant Task
participant CoroutineCreator

Schedule Thread ->>+ CoroutinePool: CoroutinePool::try_timeout_schedule_task
alt 协程池已停止
CoroutinePool ->>+ Schedule Thread: 返回错误
Expand Down
3 changes: 1 addition & 2 deletions core/docs/cn/monitor.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ fn main() -> std::io::Result<()> {

## 为什么需要抢占?

在调用`Coroutine::resume_with`后,协程可能会长时间占用调度线程,从而拖慢由该调度线程调度的其他协程。协程在两种情况下会长时间占用调度线程:陷入大量计算或系统调用。为了解决陷入大量计算的问题,我们引入抢占式调度,它会自动挂起长时间执行的协程,并允许其他协程执行。
在调用`Coroutine::resume_with`后,协程可能会长时间占用调度线程,从而拖慢由该调度线程调度的其他协程。协程在两种情况下会长时间占用调度线程:陷入重度计算或系统调用。为了解决陷入重度计算的问题,我们引入抢占式调度,它会自动挂起长时间执行的协程,并允许其他协程执行。

## 什么是monitor?

Expand All @@ -58,7 +58,6 @@ sequenceDiagram
participant 协程
participant MonitorListener
participant Monitor线程

用户线程 ->>+ 协程: Coroutine::resume_with
协程 ->>+ MonitorListener: Listener::on_state_changed
MonitorListener ->>+ Monitor线程: Monitor::submit
Expand Down
55 changes: 55 additions & 0 deletions core/docs/cn/ordered-work-steal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
title: 有序工作窃取总览
date: 2025-01-17 08:34:00
author: loongs-zhang
---

# 有序工作窃取总览

[English](../en/ordered-work-steal.md) | 中文

## 为什么需要有序工作窃取?

在现实世界中,总是有一些线程先完成自己的任务,而其他线程还有任务需要处理。于是,就会出现一核有难、多核围观的壮观场景。

<div style="text-align: center;">
<img src="../../../docs/img/watching.png" width="50%">
</div>

显然,我们不希望这种情况发生。对于空闲的线程,与其让它们围观其他线程工作,不如让它们帮助其他线程工作。此外,我们希望根据优先级执行任务,优先级越高,任务越早被执行。

## 什么是有序工作窃取队列?

有序工作窃取队列由一个全局队列和多个本地队列组成,全局队列是无界的,而本地队列是一个有界的`SkipList`集合。为了确保高性能,本地队列的数量通常等于线程的数量。值得一提的是,如果所有线程都优先处理本地任务,可能会出现一种极端情况,即共享队列上的任务永远没有机会被调度。为了避免这种不平衡,参考goroutine的设计,每次线程从本地队列调度了60个任务后,强制从共享队列中弹出`优先级最高的任务`。

## `push`的工作原理

```mermaid
flowchart TD
Cond{本地队列是否已满?}
PS[将任务推入本地队列]
PTG[将本地队列中一半的低优先级任务推入全局队列]
PG[将任务推入全局队列]
push --> Cond
Cond -- 否 --> PS
Cond -- 是 --> PTG --- PG
```

## `pop`的工作原理

```mermaid
flowchart TD
Cond1{本地队列中是否有任务?}
Cond2{其他本地队列中是否有任务?}
Cond3{全局队列中是否有任务?}
PS[弹出优先级最高的任务]
ST[从其他本地队列窃取高优先级任务]
PF[未找到任务]
pop --> Cond1
Cond1 -- 是 --> PS
Cond1 -- 否 --> Cond2
Cond2 -- 是 --> ST --> PS
Cond2 -- 否 --> Cond3
Cond3 -- 是 --> PS
Cond3 -- 否 --> PF
```
31 changes: 31 additions & 0 deletions core/docs/cn/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
title: open-coroutine总览
date: 2025-01-10 08:24:00
author: loongs-zhang
---

# open-coroutine总览

[English](../en/overview.md) | 中文

[![crates.io](https://img.shields.io/crates/v/open-coroutine.svg)](https://crates.io/crates/open-coroutine)
[![docs.rs](https://img.shields.io/badge/docs-release-blue)](https://docs.rs/open-coroutine)
[![LICENSE](https://img.shields.io/github/license/acl-dev/open-coroutine.svg?style=flat-square)](https://github.com/acl-dev/open-coroutine/blob/master/LICENSE-APACHE)
[![Build Status](https://github.com/acl-dev/open-coroutine/workflows/CI/badge.svg)](https://github.com/acl-dev/open-coroutine/actions)
[![Codecov](https://codecov.io/github/acl-dev/open-coroutine/graph/badge.svg?token=MSM3R7CBEX)](https://codecov.io/github/acl-dev/open-coroutine)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/acl-dev/open-coroutine.svg)](http://isitmaintained.com/project/acl-dev/open-coroutine "Average time to resolve an issue")
[![Percentage of issues still open](http://isitmaintained.com/badge/open/acl-dev/open-coroutine.svg)](http://isitmaintained.com/project/acl-dev/open-coroutine "Percentage of issues still open")

`open-coroutine`是一个简单、高效、通用的有栈协程库,您可以将其用作IO线程池的性能替代,查看[为什么更好](core/docs/en/why-better.md).

- [诞生之因](../../../docs/cn/background.md)
- [语言选择](../../../docs/cn/why-rust.md)
- [为什么更好](../cn/why-better.md)
- [快速开始](../../../README_ZH.md)
- [协程总览](../cn/coroutine.md)
- [可伸缩栈总览](../cn/scalable-stack.md)
- [Monitor总览](../cn/monitor.md)
- [工作窃取总览](../cn/work-steal.md)
- [有序工作窃取总览](../cn/ordered-work-steal.md)
- [协程池总览](../cn/coroutine-pool.md)
- [Hook总览](../../../hook/docs/cn/hook.md)
8 changes: 4 additions & 4 deletions core/docs/cn/scalable-stack.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ fn main() -> std::io::Result<()> {

协程的默认栈大小为128KB,这对于大多数场景来说已经足够,但仍有一些场景不适用,例如递归算法。可扩展栈允许在程序中标注可能需要更大栈的扩容点。如果栈达到其限制,则会溢出到堆中。

## How it works
## 工作原理

```mermaid
flowchart TD
Cond1{在协程中}
Cond2{达到限制}
Cond3{第一次扩容}
Cond1{在协程中?}
Cond2{达到限制?}
Cond3{第一次扩容?}
C[创建新栈]
RC[在当前栈上运行]
RN1[在新栈上运行]
Expand Down
105 changes: 105 additions & 0 deletions core/docs/cn/why-better.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
---
title: 为什么更好
date: 2025-01-10 08:28:00
author: loongs-zhang
---

# 为什么更好

[English](../en/why-better.md) | 中文

## 系统调用不会阻塞

首先,我们来看一下线程是如何与系统调用协作的。

```mermaid
sequenceDiagram
actor 用户线程
participant 操作系统
用户线程 ->>+ 用户线程: 执行
alt 用户线程被阻塞
用户线程 ->>+ 操作系统: 慢系统调用
操作系统 ->> 用户线程: 返回
end
用户线程 ->>+ 用户线程: 执行
```

如果系统调用是一个慢系统调用,例如默认阻塞的`accept`,线程将被长时间阻塞,直到操作系统返回为止,期间无法做任何事情。现在,我们来看一下 open-coroutine 是如何与系统调用协作的。

```mermaid
sequenceDiagram
actor EventLoop线程
participant 协程1
participant 协程2
participant 被代理的系统调用
participant 操作系统
EventLoop线程 ->>+ 协程1: 调度
alt 协程1逻辑上被阻塞
协程1 ->>+ 被代理的系统调用: 慢系统调用
被代理的系统调用 ->>+ 操作系统: 快系统调用
操作系统 ->> 被代理的系统调用: 返回错误码
被代理的系统调用 ->> 协程1: 挂起协程一段时间
end
协程1 ->>+ EventLoop线程: 挂起
EventLoop线程 ->>+ 协程2: 调度
alt 协程2逻辑上被阻塞
协程2 ->>+ 被代理的系统调用: 慢系统调用
被代理的系统调用 ->>+ 操作系统: 快系统调用
操作系统 ->> 被代理的系统调用: 返回
被代理的系统调用 ->> 协程2: 返回
end
协程2 ->>+ EventLoop线程: 返回
EventLoop线程 ->>+ 协程1: 调度
alt 协程1逻辑上被阻塞
协程1 ->>+ 被代理的系统调用: 从上次暂停处恢复
被代理的系统调用 ->>+ 操作系统: 快系统调用
操作系统 ->> 被代理的系统调用: 返回
被代理的系统调用 ->> 协程1: 返回
end
协程1 ->>+ EventLoop线程: 返回
EventLoop线程 ->>+ EventLoop线程: 调度其他协程
```

如你所见,`被代理的系统调用`(hook)将`慢系统调用`转换为`快系统调用`。通过这种方式,尽管`EventLoop线程`在执行系统调用时仍然会被阻塞,但阻塞时间非常短。因此,与线程模型相比,`EventLoop线程`可以在相同的时间内做更多的事情。

## 重度计算不会阻塞

其次,我们来看一下线程如何处理重度计算。

```mermaid
sequenceDiagram
actor 用户线程
alt 用户线程陷入循环
用户线程 ->>+ 用户线程: 执行循环
end
```

就像上面的系统调用一样,线程会一直阻塞在循环中。接下来,我们来看一下open-coroutine如何处理重度计算。

```mermaid
sequenceDiagram
actor EventLoop线程
participant 协程1
participant 协程2
participant Monitor
EventLoop线程 ->>+ 协程1: 调度
alt 协程1进入循环
协程1 ->>+ 协程1: 执行循环一段时间
Monitor ->> 协程1: 挂起协程
end
协程1 ->>+ EventLoop线程: 挂起
EventLoop线程 ->>+ 协程2: 调度
alt 协程2进入循环
协程2 ->>+ 协程2: 执行循环一段时间
Monitor ->> 协程1: 挂起协程
end
协程2 ->>+ EventLoop线程: 挂起
EventLoop线程 ->>+ 协程1: 调度
alt 协程1进入循环
协程1 ->>+ 协程1: 从上次暂停处恢复
end
协程1 ->>+ EventLoop线程: 返回
EventLoop线程 ->>+ EventLoop线程: 调度其他协程
```

`Monitor`会监控协程的执行情况,一旦发现某个协程的执行时间过长,就会强制挂起该协程。因此,现在我们甚至可以[使用一个`EventLoop线程`来执行多个循环](https://github.com/loongs-zhang/open-coroutine/blob/master/open-coroutine/examples/preemptive.rs),这是单线程模型无法实现的。
55 changes: 55 additions & 0 deletions core/docs/cn/work-steal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
title: 工作窃取总览
date: 2025-01-17 08:34:00
author: loongs-zhang
---

# 工作窃取总览

[English](../en/work-steal.md) | 中文

## 为什么需要工作窃取?

在现实世界中,总是有一些线程先完成自己的任务,而其他线程还有任务需要处理。于是,就会出现一核有难、多核围观的壮观场景。

<div style="text-align: center;">
<img src="../../../docs/img/watching.png" width="50%">
</div>

显然,我们不希望这种情况发生。对于空闲的线程,与其让它们围观其他线程工作,不如让它们帮助其他线程工作。

## 什么是工作窃取队列?

工作窃取队列由一个全局队列和多个本地队列组成,全局队列是无界的,而本地队列是一个有界的环形缓冲区(RingBuffer)。为了确保高性能,本地队列的数量通常等于线程的数量。值得一提的是,如果所有线程都优先处理本地任务,可能会出现一种极端情况,即共享队列上的任务永远没有机会被调度。为了避免这种不平衡,参考goroutine的设计,每次线程从本地队列调度了60个任务后,强制从共享队列中弹出一个任务。

## `push`的工作原理

```mermaid
flowchart TD
Cond{本地队列是否已满?}
PS[将任务推入本地队列]
PTG[将本地队列中一半的任务推入全局队列]
PG[将任务推入全局队列]
push --> Cond
Cond -- 否 --> PS
Cond -- 是 --> PTG --- PG
```

## `pop`的工作原理

```mermaid
flowchart TD
Cond1{本地队列中是否有任务?}
Cond2{其他本地队列中是否有任务?}
Cond3{全局队列中是否有任务?}
PS[弹出一个任务]
ST[从其他本地队列窃取任务]
PF[未找到任务]
pop --> Cond1
Cond1 -- 是 --> PS
Cond1 -- 否 --> Cond2
Cond2 -- 是 --> ST --> PS
Cond2 -- 否 --> Cond3
Cond3 -- 是 --> PS
Cond3 -- 否 --> PF
```
1 change: 0 additions & 1 deletion core/docs/en/coroutine-pool.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ sequenceDiagram
participant WorkerCoroutine
participant Task
participant CoroutineCreator

Schedule Thread ->>+ CoroutinePool: CoroutinePool::try_timeout_schedule_task
alt the coroutine pool is stopped
CoroutinePool ->>+ Schedule Thread: return error
Expand Down
1 change: 0 additions & 1 deletion core/docs/en/monitor.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ sequenceDiagram
participant Coroutine
participant MonitorListener
participant Monitor Thread

User Thread ->>+ Coroutine: Coroutine::resume_with
Coroutine ->>+ MonitorListener: Listener::on_state_changed
MonitorListener ->>+ Monitor Thread: Monitor::submit
Expand Down
7 changes: 4 additions & 3 deletions core/docs/en/ordered-work-steal.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ author: loongs-zhang

# Ordered Work Steal Overview

English | [中文](../cn/ordered-work-steal.md)

## Why ordered work steal?

In the real world, there are always threads that complete their own tasks first, while other threads have tasks to be
Expand All @@ -16,8 +18,8 @@ processed. Then, a spectacular scene emerged where one core was in difficulty an
</div>

Obviously, we don't want this to happen. For idle threads, instead of letting them watch other threads working, it's
better to let them help other threads work. In addition, we hope to pop tasks based on priority, the higher the
priority, the earlier it will be popped up.
better to let them help other threads work. In addition, we hope to execute tasks based on priority, the higher the
priority, the earlier it will be executed.

## What is ordered work steal queue?

Expand All @@ -39,7 +41,6 @@ flowchart TD
push --> Cond
Cond -- No --> PS
Cond -- Yes --> PTG --- PG

```

## How `pop` works
Expand Down
2 changes: 2 additions & 0 deletions core/docs/en/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ author: loongs-zhang

# open-coroutine overview

English | [中文](../cn/overview.md)

[![crates.io](https://img.shields.io/crates/v/open-coroutine.svg)](https://crates.io/crates/open-coroutine)
[![docs.rs](https://img.shields.io/badge/docs-release-blue)](https://docs.rs/open-coroutine)
[![LICENSE](https://img.shields.io/github/license/acl-dev/open-coroutine.svg?style=flat-square)](https://github.com/acl-dev/open-coroutine/blob/master/LICENSE-APACHE)
Expand Down
4 changes: 2 additions & 2 deletions core/docs/en/scalable-stack.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ where the stack may want to grow larger. Spills over to the heap if the stack ha

```mermaid
flowchart TD
Cond1{In coroutine}
Cond2{Approach the limit}
Cond1{In coroutine?}
Cond2{Approach the limit?}
Cond3{Is the first growing up?}
C[Create a new stack]
RC[Run code on current stack]
Expand Down
Loading