| RFC-0007:Zircon 移除了线程终止 | |
|---|---|
| 状态 | 已接受 |
| 区域 |
|
| 说明 | 本文档讨论了线程终止功能的移除以及移除背后的原因。 |
| Gerrit 更改 | |
| 作者 | |
| 审核人 | |
| 提交日期(年-月-日) | 2020-09-25 |
| 审核日期(年-月-日) | 2020-10-06 |
摘要
过去,zx_task_kill 允许用户模式杀死单个线程。不过,终止单个线程会鼓励不良做法,并且很可能会使进程处于不良状态。因此,应移除终止单个线程的功能。
动机和问题陈述
用户模式下没有合理的用途来终止单个线程。公开此类功能会鼓励不良做法。
在 Fuchsia 上,与在其他系统中一样,终止线程是异步完成的;对于正在运行的线程,没有实际可行的方法来确定可以安全终止线程的确切位置。对于被阻塞(等待)的线程,更安全且通常更简单的解决方案是添加逻辑,以便线程在唤醒时自行退出。
终止线程的危险
- 锁可以保持获取状态,包括控制堆的全局锁。
- 可能会发生内存泄漏。至少是线程堆栈,但通常是许多其他部分。
- 运行时处于不一致状态。至少对于 C 和 Go 运行时是这样。
- 在线程前往系统调用的过程中将其终止会导致进程处于未知状态。内核没问题,但进程无法知道发生了什么以及没有发生什么。
- 会破坏 RAII 封装容器和自动清理。事实上,它会破坏 Fuchsia 使用的大多数高级语言的保证。
设计
当向以下系统调用传递线程句柄时,该系统调用将失败并显示 ZX_ERR_NOT_SUPPORTED:
zx_status_t zx_task_kill(zx_handle_t handle);
进程和作业仍可正常终止。
实现
幸运的是,Fuchsia 中很少使用线程终止。唯一用例是在测试代码中检查线程是否遇到特定异常。此代码将进行更新,以便在处理完异常后,抛出异常的线程自行退出。对于异常无法恢复的代码,可以在线程恢复之前将发生异常的线程的指令指针直接设置为 zx_thread_exit 或运行时的线程退出函数。这些测试可能仍会泄露异常线程在堆上存储的内容,但运行时处于更好的状态,并且在测试进程退出时会收集泄露的内容。
性能
不适用
安全注意事项
不适用
隐私注意事项
不适用
测试
将更新 zircon 核心测试,以确保 zx_task_kill 系统调用按预期运行。 可以进行一些静态分析,以查找传递线程的 zx_task_kill 的调用点。
我们将遵循完整的 Fuchsia 大规模变更 (LSC) 流程,以确保此变更经过适当的测试。
文档
zx_task_kill 的文档将更新,以反映线程不可被终止。
缺点、替代方案和未知因素
此提案的替代方案是当前现状,即允许终止线程。在 Fuchsia 的整个历史记录中,线程一直都是可终止的,但还没有任何可接受的用例表明程序依赖于此行为。因此,我们认为可以安全地移除线程终止。