<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://ocr.michiyo.me/w/index.php?action=history&amp;feed=atom&amp;title=API%2Fthread%2Fzh</id>
	<title>API/thread/zh - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://ocr.michiyo.me/w/index.php?action=history&amp;feed=atom&amp;title=API%2Fthread%2Fzh"/>
	<link rel="alternate" type="text/html" href="https://ocr.michiyo.me/w/index.php?title=API/thread/zh&amp;action=history"/>
	<updated>2026-08-24T15:14:13Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://ocr.michiyo.me/w/index.php?title=API/thread/zh&amp;diff=1055&amp;oldid=prev</id>
		<title>imported&gt;OCDoc Import: Imported from legacy OpenComputers documentation at ocdoc.cil.li</title>
		<link rel="alternate" type="text/html" href="https://ocr.michiyo.me/w/index.php?title=API/thread/zh&amp;diff=1055&amp;oldid=prev"/>
		<updated>2026-08-24T08:08:27Z</updated>

		<summary type="html">&lt;p&gt;Imported from legacy OpenComputers documentation at ocdoc.cil.li&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= Thread(线程) API =&lt;br /&gt;
&lt;br /&gt;
Thread(线程) API为OpenOS提供了协程的一种变体。线程比基础的协程在很多方面都更高级，并且对很多工作流程而言都更易用。OpenOS线程是自主的，非阻塞的，可分离的进程。&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;自主性：&amp;#039;&amp;#039;&amp;#039;线程在创建后会立即开始异步执行，无需调用resume。与协程不同，线程在yield后会自恢复，且不会回到创建线程的代码行。使用协程进行编程基于用户显式进行的协作yield和resume调用。然而，在线程中yield或调用`event.pull`，只会暂时阻塞线程，线程将自行继续运行。&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;非阻塞性：&amp;#039;&amp;#039;&amp;#039;线程可以调用`computer.pullSignal`（或其更高级别的包装，如`event.pull`、`io.pull`等），而不会阻塞主内核进程或任何其他线程。当然线程本身会被阻塞，直到出现信号或超时。线程的计算流程与在命令行中运行相同的代码一样。在幕后，thread(线程)库使用`pullSignal`在线程之间切换，并在适当的时候唤醒线程。这与协程完全不同，在协程中，`computer.pullSignal`会阻塞系统上的所有其他活动，直到出现信号或超时。&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;可分离性：&amp;#039;&amp;#039;&amp;#039;默认情况下，线程由创建它们的进程拥有（注意线程本身就是一个进程）。拥有线程的进程被称为其父进程。父进程关闭（即执行完毕）时会关闭所有正在运行的子线程（将子线程join到父进程）。但是在以下情况下，进程不必关闭线程：&lt;br /&gt;
&lt;br /&gt;
* 线程从父进程上分离。参见`t:detach()`。请注意线程也可以附着于其他父进程，参见`t:attach()`。&lt;br /&gt;
&lt;br /&gt;
* 父进程抛出了异常或调用了`os.exit`，此时所有附着在上面的线程都会被杀死。请注意，重启也会杀死所有线程。&lt;br /&gt;
&lt;br /&gt;
* 线程被杀死，参见`t:kill()`。&lt;br /&gt;
&lt;br /&gt;
* 线程被手动暂停，参见`t:suspend()`。&lt;br /&gt;
&lt;br /&gt;
=== 独立事件注册 ===&lt;br /&gt;
&lt;br /&gt;
每个线程都维护了一套独立的事件注册机制；不继承也不分享。线程中创建的所有事件注册记录（即侦听器或定时器）都只从属于此线程。&lt;br /&gt;
&lt;br /&gt;
* 线程结束时，其所有事件注册记录都会随之结束。&lt;br /&gt;
* `suspended`（暂停的）线程会忽略事件（参见`t:status() suspended`）&lt;br /&gt;
* 一个线程不可以访问/移除/交互其他线程的事件注册记录。&lt;br /&gt;
* 被推送的事件对系统中的所有运行中线程可见。&lt;br /&gt;
* 两个独立的线程可以对同一个事件`event.pull`，每个线程都会独立观测到此事件。&lt;br /&gt;
&lt;br /&gt;
== 概述 ==&lt;br /&gt;
&lt;br /&gt;
线程主要有两种用途是其他选择无法提供：&lt;br /&gt;
&lt;br /&gt;
* 你需要编写一个函数，其中进行了阻塞式调用，但不阻塞程序其它部分的运行。 - 你需要编写长期运行的后台函数，而不想手动管理其yield与resum。&lt;br /&gt;
&lt;br /&gt;
== 函数 ==&lt;br /&gt;
&lt;br /&gt;
此处定义了两类API。&lt;br /&gt;
&lt;br /&gt;
1. [[API/thread/zh#线程API|线程]]API，或者说静态函数，由`require(&amp;quot;thread&amp;quot;)`提供。 2. [[API/thread/zh#线程句柄API|线程句柄]]API，或者说适用于`thread.create`创建的线程_对象_的api。在此文档中这些线程句柄将会仅以`t`表示。&lt;br /&gt;
&lt;br /&gt;
== 线程API ==&lt;br /&gt;
&lt;br /&gt;
* `thread.create(thread_proc: function[, ...]): table`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;开启一个执行函数`thread_proc`的新线程，并返回其线程句柄，参见[[API/thread/zh#线程句柄API|线程句柄API]]。此方法可接收可选的`...`参数，这些参数将会被传递给`thread_proc`。 线程将自动开始运行。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
```lua local thread = require(&amp;quot;thread&amp;quot;) print(&amp;quot;Main program start&amp;quot;) thread.create(function(a, b)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;print(a)&lt;br /&gt;
os.sleep()&lt;br /&gt;
print(b)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end, &amp;#039;A&amp;#039;, &amp;#039;B&amp;#039;) print(&amp;quot;Main program end&amp;quot;) ```&lt;br /&gt;
&lt;br /&gt;
输出： ``` Main program start A Main program end B ```&lt;br /&gt;
&lt;br /&gt;
* `thread.waitForAll(threads: table[, timeout: number]): boolean, string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;等待给出的`threads`全部执行完成。此阻塞式操作可以在给出的`timeout`秒超时时间后返回，若给出此值的话。返回值为是否成功，若失败还会返回报错信息。线程可以在多种条件下被认定为”执行完成“，详见`t:join()`。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
```lua local thread = require(&amp;quot;thread&amp;quot;) print(&amp;quot;Main program start&amp;quot;) local t = thread.create(function(a, b)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;print(a)&lt;br /&gt;
os.sleep()&lt;br /&gt;
print(b)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end, &amp;#039;A&amp;#039;, &amp;#039;B&amp;#039;) thread.waitForAll({t}) print(&amp;quot;Main program end&amp;quot;) ```&lt;br /&gt;
&lt;br /&gt;
输出： ``` Main program start A B Main program end ```&lt;br /&gt;
&lt;br /&gt;
* `thread.waitForAny(threads: table[, timeout: number): boolean, string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;等待给出线程中的某一个完成，其他方面`thread.waitForAll()`一致。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
```lua local thread = require(&amp;quot;thread&amp;quot;) print(&amp;quot;Main program start&amp;quot;) local t1 = thread.create(function(a, b)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;print(a)&lt;br /&gt;
os.sleep()&lt;br /&gt;
print(b)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end, &amp;#039;A&amp;#039;, &amp;#039;B&amp;#039;) local t2 = thread.create(function(c, d)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;print(c)&lt;br /&gt;
os.sleep()&lt;br /&gt;
os.sleep()&lt;br /&gt;
print(d)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end, &amp;#039;C&amp;#039;, &amp;#039;D&amp;#039;) thread.waitForAny({t1, t2}) print(&amp;quot;Main program end&amp;quot;) ```&lt;br /&gt;
&lt;br /&gt;
输出： ``` Main program start A C B Main program end D ```&lt;br /&gt;
&lt;br /&gt;
请注意线程恢复的顺序并未指定，此样例中也有可能在输出&amp;quot;Main program end&amp;quot;之前就输出&amp;quot;D&amp;quot;。&lt;br /&gt;
&lt;br /&gt;
* `thread.current(): table`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;返回当前线程对象`t`。init进程不代表任何线程，此函数在init进程内而且不在任何线程内调用时不会有返回值。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== 线程句柄API ==&lt;br /&gt;
&lt;br /&gt;
* `t:resume(): boolean, string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;恢复（或者说解冻）一个暂停的线程。返回操作是否成功，若失败额外返回一条报错信息。线程在创建时直接就是运行状态，因此在基本的线程工作流程中完全用不到调用`t:resume()`。“运行中”的线程会自动继续，直到执行完毕。只有在需要恢复被暂停的（`t:suspend()`）线程时才需要`t:resume()`。**请注意，**因为你不是直接恢复线程，线程抛出的一切异常都会被线程运行库吸收，不会暴露给你的进程。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* 目前还无法为线程挂载异常处理函数，但是现在可以用`event.onError`将报错信息输出到&amp;quot;/tmp/event.log&amp;quot;。请注意目前硬中断异常只会抛出一次，并且在抛出硬中断时，带线程的进程执行的行为仍未指定。目前，任何一个线程或父进程都可能接收到异常。这些细节并不是线程规范的一部分，任何实现细节的部分都可能在以后发生变化。&lt;br /&gt;
&lt;br /&gt;
* `t:suspend(): boolean, string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;暂停（或者说冻结）一个运行中的线程。返回操作是否成功，若失败额外返回一条报错信息。“暂停的”线程不会自动唤醒，也不会随其父进程（若附有的话）结束而结束。暂停的线程会忽略出现的事件，代表此线程中定义的任何事件侦听器和定时器都不会响应事件通知。请注意线程不会缓存事件信号，暂停的线程可能会错失其等待的信号。例如，假设一个线程最近一次使用了`event.pull(&amp;quot;modem_message&amp;quot;)`等待信号，并且被“暂停”了，此时电脑收到了一条&amp;quot;modem_message&amp;quot;。这样线程将错失事件，永远不知道发生了什么。请注意如果你暂停了一条正在被阻塞以等待事件的线程，线程下次被唤醒时会接收到什么事件是未指定的。&lt;br /&gt;
&lt;br /&gt;
暂停当前线程就会导致线程立刻yield，在其他地方显式调用`t:resume()`之前也不会恢复。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;`t:resume`和`t:suspend`的特别注释&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
不要把这两个方法当作`coroutine.resume()`和`coroutine.yield()`。这两个方法是间接的，而且线程是独自异步开始或停止运行的。请将这一特性与协程方法相对比，协程方法是直接的，而且会立即唤起或离开协程的执行。参考这些样例：&lt;br /&gt;
&lt;br /&gt;
```lua local thread = require(&amp;quot;thread&amp;quot;) local t -- 此样例需要t的upvalue t = thread.create(function()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;print(&amp;quot;start&amp;quot;)&lt;br /&gt;
thread.current():suspend()&lt;br /&gt;
print(&amp;quot;after suspend&amp;quot;)&lt;br /&gt;
os.sleep()&lt;br /&gt;
print(&amp;quot;after sleep&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end) ```&lt;br /&gt;
&lt;br /&gt;
输出： ``` start ```&lt;br /&gt;
&lt;br /&gt;
```lua local thread = require(&amp;quot;thread&amp;quot;) local t -- this example needs an upvalue to t t = thread.create(function()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;print(&amp;quot;start&amp;quot;)&lt;br /&gt;
thread.current():suspend()&lt;br /&gt;
print(&amp;quot;after suspend&amp;quot;)&lt;br /&gt;
os.sleep()&lt;br /&gt;
print(&amp;quot;after sleep&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end) print(&amp;quot;outside thread create&amp;quot;) t:resume() print(&amp;quot;after resume&amp;quot;) ```&lt;br /&gt;
&lt;br /&gt;
输出： ``` start outside thread create after suspend after resume after sleep ```&lt;br /&gt;
&lt;br /&gt;
* `t:kill()`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;给它一刀！将线程杀死。线程将会被终止，不能再继续执行其线程函数。它的所有事件注册记录也都会随之结束。请注意核心底层实际上是Lua协程，协程不是抢占式线程。因此线程的结束点是可知的，意味着你可以预测线程结束的准确位置。参考此样例：&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
```lua local thread = require(&amp;quot;thread&amp;quot;) local t = thread.create(function()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;while true do&lt;br /&gt;
  print(&amp;quot;running&amp;quot;)&lt;br /&gt;
  print(&amp;quot;still running&amp;quot;)&lt;br /&gt;
  os.sleep()&lt;br /&gt;
  print(&amp;quot;after sleep&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
print(&amp;quot;unreachable code&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end) print(&amp;quot;before kill&amp;quot;) t:kill() print(&amp;quot;after kill&amp;quot;) ```&lt;br /&gt;
&lt;br /&gt;
输出： ``` running still running before kill after kill ```&lt;br /&gt;
&lt;br /&gt;
* `t:status(): string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;以字符串形式返回线程状态。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;&amp;quot;running&amp;quot; 运行&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;运行中的线程会在yield和阻塞式调用后继续运行（自动重新开始活动），直到其线程函数退出。这是创建后线程的初始与默认状态。线程就算在阻塞或不活动的状态下也会保持“运行”状态。运行中的线程可以被暂停（`t:suspend()`）或杀死（`t:kill()`），但是不可以恢复（`t:resume()`）。运行中的线程将会阻塞`t:join()`的调用，也会阻塞其父进程的关闭。与协程不同，协程在未执行时即为“暂停”状态，而线程就算在等待事件时也是“运行”状态。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;&amp;quot;suspended&amp;quot; 暂停&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;被暂停的线程会保持暂停状态，永远不会自动恢复执行其线程函数。暂停的线程会在其附着的父进程关闭时或你试图`t:join()`它时自动被杀死。暂停的线程会忽略事件信号，此线程的上下文所创建的，或其创建的任何子线程所创建的事件注册记录，也都会忽略事件信号。暂停线程的子线程表现会与暂停一样，即使其状态为“运行”。暂停的线程可以恢复（`t:resume()`）或者杀死（`t:kill()`），但不可以暂停（`t:suspend()`）。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;&amp;quot;dead&amp;quot; 死亡&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;死亡的线程是结束了或放弃了自己的运行或被终止的线程。它不可被恢复（`t:resume()`）也不可被暂停（`t:suspend()`）。死亡的线程不会阻塞父进程的关闭。杀死死亡的线程不会报错，而是什么也不做。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
** 状态样例 **&lt;br /&gt;
&lt;br /&gt;
```lua local thread = require(&amp;quot;thread&amp;quot;) local t = thread.create(function()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;print(&amp;quot;before sleep&amp;quot;)&lt;br /&gt;
os.sleep()&lt;br /&gt;
print(&amp;quot;after sleep&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end) print(t:status()) ```&lt;br /&gt;
&lt;br /&gt;
输出： ``` before sleep running after sleep ```&lt;br /&gt;
&lt;br /&gt;
```lua local thread = require(&amp;quot;thread&amp;quot;) local t = thread.create(function()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;print(&amp;quot;before sleep&amp;quot;)&lt;br /&gt;
os.sleep()&lt;br /&gt;
print(&amp;quot;after sleep&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end) t:suspend() print(t:status()) os.sleep(10) print(t:status()) t:resume() print(&amp;quot;after resume&amp;quot;) print(t:status()) ```&lt;br /&gt;
&lt;br /&gt;
输出： ``` before sleep suspended suspended after resume dead ```&lt;br /&gt;
&lt;br /&gt;
* `t:attach([level: number]): boolean, string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;将一个线程附着到一个进程，通常称为子线程或附着线程。`level`为可选参数，可用于获取父进程，传递0或`nil`则使用当前运行进程。在最初创建线程时，线程已经被附着于当前进程。若`level`指向了不存在的线程，则此方法会返回`nil`与一条报错信息，否则返回true。附着的线程将会阻塞其父进程的关闭，直到线程死亡（或者被杀死，或者父进程放弃执行）。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* `t:detach(): table, string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;将一个线程从其父进程（若有）上解除附着。若未执行动作则返回`nil`与一条报错信息，否则返回自身（以便于你想在同一行中创建一个线程并将其解除附着）。解除附着的线程会继续执行，直到电脑关机或重启，或者线程死亡。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
```lua local detached_thread = thread.create(function() end):detach() ```&lt;br /&gt;
&lt;br /&gt;
* `t:join([timeout: number]): boolean, string`&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;阻塞调用者，直到`t`不再运行。或者在到达了`timeout`秒的超时时间后返回`false`（可选）。在`t:join()`的调用结束后线程的状态将为“死亡”。任一下列情况都会导致`join`结束并停止阻塞调用者：&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* 线程继续运行，直到其从线程函数中返回。&lt;br /&gt;
* 线程被放弃，或抛出了未被捕获的异常。&lt;br /&gt;
* 线程被暂停。&lt;br /&gt;
* 线程被杀死&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;调用`thread.waitForAll({t})`在功能上与调用`t:join()`一致。在进程结束时会对其子线程调用`thread.waitForAll`（若有）。子线程也通过同样的机制阻塞其父进程。&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== 线程异常样例 ==&lt;br /&gt;
&lt;br /&gt;
此样例演示了线程抛出异常时会发生什么。线程在抛出未捕获的异常时会停止执行并进入“死亡”状态。报错信息将不会输出到stdout或stderr（详见`t:resume()`）。&lt;br /&gt;
&lt;br /&gt;
```lua local thread = require(&amp;quot;thread&amp;quot;) local tty = require(&amp;quot;tty&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;p start&amp;quot;) local reader = thread.create(function()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;print(&amp;quot;reader start&amp;quot;)&lt;br /&gt;
error(&amp;quot;thread abort&amp;quot;) -- 抛出一个异常&lt;br /&gt;
print(&amp;quot;reader done&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end) print(&amp;quot;p end&amp;quot;, reader:status()) ```&lt;br /&gt;
&lt;br /&gt;
输出： ``` p start reader start p end dead ```&lt;br /&gt;
&lt;br /&gt;
== 线程中断处理函数样例 ==&lt;br /&gt;
&lt;br /&gt;
此样例演示了你该如何注册处理软中断（^c）的函数，用于关闭文件句柄、释放资源等等，然后退出整个程序。&lt;br /&gt;
&lt;br /&gt;
```lua local thread = require(&amp;quot;thread&amp;quot;) local event = require(&amp;quot;event&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
local cleanup_thread = thread.create(function()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;event.pull(&amp;quot;interrupted&amp;quot;)&lt;br /&gt;
print(&amp;quot;cleaning up resources&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end)&lt;br /&gt;
&lt;br /&gt;
local main_thread = thread.create(function()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;print(&amp;quot;main program&amp;quot;)&lt;br /&gt;
while true do&lt;br /&gt;
  io.write(&amp;quot;input: &amp;quot;)&lt;br /&gt;
  io.read()&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end)&lt;br /&gt;
&lt;br /&gt;
thread.waitForAny({cleanup_thread, main_thread}) os.exit(0) -- 关闭所有剩余线程 ```&lt;br /&gt;
&lt;br /&gt;
假设用户按下了^c发送了一次软中断&lt;br /&gt;
&lt;br /&gt;
输出： ``` main program input: ^c cleaning up resources ```&lt;br /&gt;
&lt;br /&gt;
== 非阻塞式线程Yield/Pull操作样例 ==&lt;br /&gt;
&lt;br /&gt;
此样例演示了现在OpenOS可支持非阻塞式线程。&lt;br /&gt;
&lt;br /&gt;
```lua local event = require(&amp;quot;event&amp;quot;) local thread = require(&amp;quot;thread&amp;quot;) thread.create(function()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;a,b,c,d,e,f,g = coroutine.yield()&lt;br /&gt;
print(a,b,c,d,e,f,g)&lt;br /&gt;
print(event.pull())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
end)&lt;br /&gt;
&lt;br /&gt;
event.push(&amp;quot;custom_event_a&amp;quot;) print(&amp;quot;done&amp;quot;) event.push(&amp;quot;custom_event_b&amp;quot;, 2) ```&lt;br /&gt;
&lt;br /&gt;
输出： ``` custom_event_a done custom_event_b 2 ```&lt;br /&gt;
&lt;br /&gt;
== 目录 ==&lt;br /&gt;
&lt;br /&gt;
{{:API/contents/zh}}&lt;br /&gt;
&lt;/div&gt;</summary>
		<author><name>imported&gt;OCDoc Import</name></author>
	</entry>
</feed>