This shows you the differences between two versions of the page.
Next revision | Previous revision Next revision Both sides next revision | ||
api:thread:zh [2022/08/11 10:49] fight_xing created |
api:thread:zh [2023/10/20 11:22] hfsr [Functions] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Thread API ====== | + | ====== Thread(线程) API ====== |
+ | Thread(线程) API为OpenOS提供了协程的一种变体。线程比基础的协程在很多方面都更高级,并且对很多工作流程而言都更易用。OpenOS线程是自主的,非阻塞的,可分离的进程。 | ||
- | **本篇文章的部分/全部内容还没有进行翻译。** | + | * **自主性:**线程在创建后会立即开始异步执行,无需调用resume。与协程不同,线程在yield后会自恢复,且不会回到创建线程的代码行。使用协程进行编程基于用户显式进行的协作yield和resume调用。然而,在线程中yield或调用`event.pull`,只会暂时阻塞线程,线程将自行继续运行。 |
- | The Thread API provides a variation of coroutines for openos. A thread is superior to basic coroutines in many ways and, for many workflows, is easier to work with. An openos thread is an autonomous non-blocking detachable process. | ||
- | * **Autonomous**: Threads asynchronously begin execution immediately after creation without needing to call resume. Unlike coroutines, threads self-resume after yielding and do not yield back to the line of code where they were created. Programming with coroutines builds on the cooperative yield and resume calls made explicitly by the user. Yielding or calling `event.pull` from a thread, however, only temporarily blocks just that thread and will continue on its own. | + | * **非阻塞性:**线程可以调用`computer.pullSignal`(或其更高级别的包装,如`event.pull`、`io.pull`等),而不会阻塞主内核进程或任何其他线程。当然线程本身会被阻塞,直到出现信号或超时。线程的计算流程与在命令行中运行相同的代码一样。在幕后,thread(线程)库使用`pullSignal`在线程之间切换,并在适当的时候唤醒线程。这与协程完全不同,在协程中,`computer.pullSignal`会阻塞系统上的所有其他活动,直到出现信号或超时。 |
- | * **Non-Blocking**: Threads can call `computer.pullSignal` (or any higher level wrapper such as `event.pull`, `io.pull`, etc) without blocking the main kernel process nor any other thread. The thread itself is blocked until a signal or timeout occurs. The computational flow of the thread behaves just as if the same code were run in a script from the command line. Behind the scenes, the thread library is using pullSignal to swap between threads, and waking threads up when appropriate. This is very much unlike coroutines where `computer.pullSignal` blocks all other activity on the system until a signal or timeout occurs. | + | * **可分离性:**默认情况下,线程由创建它们的进程拥有(注意线程本身就是一个进程)。拥有线程的进程被称为其父进程。父进程关闭(即执行完毕)时会关闭所有正在运行的子线程(将子线程join到父进程)。但是在以下情况下,进程不必关闭线程: |
+ | * 线程从父进程上分离。参见`t:detach()`。请注意线程也可以附着于其他父进程,参见`t:attach()`。 | ||
- | * **Detachable**: By default, threads are owned by the process in which they are created (note that threads themselves are a process). The owning process is known as the parent process. When a parent process is closing (i.e. it has reached the end of its execution) it will close(i.e. join) all of its running child threads. A process does not have to close a thread when: | + | * 父进程抛出了异常或调用了`os.exit`,此时所有附着在上面的线程都会被杀死。请注意,重启也会杀死所有线程。 |
+ | * 线程被杀死,参见`t:kill()`。 | ||
- | * The thread detaches from the parent process. see `t:detach()`. Note that a thread can also attach to another parent. see `t:attach()` | + | * 线程被手动暂停,参见`t:suspend()`。 |
- | * The parent process throws an exception or calls `os.exit` in which case all attached threads are killed. Note that rebooting also kills all threads. | + | ====独立事件注册==== |
- | * The thread is killed. see `t:kill()` | + | 每个线程都维护了一套独立的事件注册机制;不继承也不分享。线程中创建的所有事件注册记录(即侦听器或定时器)都只从属于此线程。 |
+ | * 线程结束时,其所有事件注册记录都会随之结束。 | ||
+ | * `suspended`(暂停的)线程会忽略事件(参见`t:status() suspended`) | ||
+ | * 一个线程不可以访问/移除/交互其他线程的事件注册记录。 | ||
+ | * 被推送的事件对系统中的所有运行中线程可见。 | ||
+ | * 两个独立的线程可以对同一个事件`event.pull`,每个线程都会独立观测到此事件。 | ||
+ | ===== 概述 ===== | ||
- | * The thread is manually suspended. see `t:suspend()` | + | 线程主要有两种用途是其他选择无法提供: |
- | ====Event Registration Independence==== | + | - 你需要编写一个函数,其中进行了阻塞式调用,但不阻塞程序其它部分的运行。 |
- | + | - 你需要编写长期运行的后台函数,而不想手动管理其yield与resum。 | |
- | A thread maintains an independent set of event registrations; it does not inherit any and it does not share any. Any event registration made (e.g. listeners or timers) inside a thread belongs to that thread. | + | |
- | * When a thread dies all of its event registrations die with it. | + | |
- | * A `suspended` thread ignores events (see `t:status() suspended`) | + | |
- | * A thread cannot access/remove/interfere with another thread's event registrations. | + | |
- | * A pushed event is observed by all running threads on the system. | + | |
- | * Two separate threads can `event.pull` for the same event, and each thread will observe the event independently. | + | |
- | ===== Overview ===== | + | |
- | + | ||
- | There are two main use cases for using threads over other viable options | + | |
- | + | ||
- | - You want to write a function that makes blocking calls without blocking the rest of your application. | + | |
- | - You want a long running background function without having to manage yielding and resuming it manually. | + | |
===== Functions ===== | ===== Functions ===== | ||
Line 41: | Line 37: | ||
There are two sections of API defined here. | There are two sections of API defined here. | ||
- | 1. The [[api:thread#Thread_API|thread]] api, or the static functions, provided by `require("thread")` | + | 1. [[api:thread:zh#线程API|线程]]api,或者说静态函数,由`require("thread")`提供。 |
- | 2. The [[api:thread#Thread_Handle_API|thread handle]] api, or the api available the thread _objects_ created by `thread.create`. In this documentation these thread handles will be denoted by just `t`. | + | 2. [[api:thread:zh#线程句柄API|线程句柄]] api,或者说适用于`thread.create`创建的线程_对象_的api。在此文档中这些线程句柄将会仅以`t`表示。 |
===== Thread API ===== | ===== Thread API ===== |