Linux 下有暂停线程执行的 API 吗?

2020-01-28 17:39:40 +08:00
 nyanyh

pause()可以暂停,但是要求设置 signal handler

Windows 有 SuspendThread() / ResumeThread() macOS 有 thread_suspend() / thread_resume() 一些 BSD 也实现了 pthread_suspend_np()

看了下 XNU 和 FreeBSD 的源码,都是在内核里实现了暂停机制

需求就是不在线程内部进行任何处理的前提下,从外部暂停线程执行

while(true){}
5908 次点击
所在节点    Linux
19 条回复
ipwx
2020-01-28 17:43:05 +08:00
标准 posix 没有吧。但是 sleep 以及所有系统的 io 调用都是可以打断的应该
nyanyh
2020-01-28 17:46:06 +08:00
@ipwx #1 单纯一个 while(true)空循环,这种线程没办法从外部打断呀
我想了个 trick,如果能在指定线程 context 下执行代码(类似 Windows 下的 APC ),然后上个 pthread_cond 应该可以实现我的效果,但是我也没有找到 Linux 下怎么在另一个 context 下执行代码的方法
CismonX
2020-01-28 17:56:17 +08:00
标准 posix 的话,可以用 pthread_sigmask + sigwait + pthread_kill 来暂停线程,signal handler 是必不可少的
712e1959
2020-01-28 18:15:59 +08:00
^z
?
nyanyh
2020-01-28 18:36:25 +08:00
@CismonX #3 pthread_sigmask 要在线程内调用,线程外不行
nyanyh
2020-01-28 18:36:48 +08:00
@712e1959 #4 ^z 发送的 SIGTSTP,会暂停整个进程
ipwx
2020-01-28 20:12:24 +08:00
@nyanyh 我觉得你不必纠结这个问题。一个好的多线程程序一般不依赖这种外部 suspend 来结束线程,因为这容易导致线程没清理干净资源。还是应该有个协调退出的机制。
nightwitch
2020-01-28 21:08:20 +08:00
The POSIX standard provides no mechanism by which a thread A can suspend the execution of another thread B, without cooperation from B. The only way to implement a suspend/restart mechanism is to have B check periodically some global variable for a suspend request and then suspend itself on a condition variable, which another thread can signal later to restart B.
翻译一下:POSIX 标准没有提供机制,让线程 A 在没有线程 B 的协作下暂停线程 B 的执行。

要想处理这种问题的话,信号处理或者使用条件变量吧。
有关 pthread_sigmask 的问题,pthread_sigmask 会继承当前的 mask, 你可以在 main 里定义好需要的 sigmask, 新建的线程会继承 mask。

使用信号会带来一些其他问题,比如外部给进程发信号,内核会地送到任意没有阻塞该信号的线程,可能会导致意料之外的线程睡眠 /唤醒。
las917vki
2020-01-28 22:49:28 +08:00
Windows 这些操作其他线程、进程上下文的 API 是十分粗暴和低级的…
而且当年添加这些 API 本质上是为了适应 Win32 程序一些乱七八糟的设计问题…( UI 上
正常的程序员都应该使用标准的 wake 和 wait 成对来操作。
monsterxx03
2020-01-28 23:03:40 +08:00
PTRACE_ATTACH
ysc3839
2020-01-29 03:10:33 +08:00
@las917vki 那 macOS 为什么也有呢?
ysc3839
2020-01-29 03:12:32 +08:00
@las917vki 而且据微软文档所说 https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-suspendthread#remarks

> This function is primarily designed for use by debuggers.
lqf96
2020-01-29 07:26:07 +08:00
@nyanyh 突发奇想,cgroup freezer 不知道有没有用,当然这个肯定只有 linux 有...之后就好办了,读写内存就用 process_vm_readv 和 process_vm_writev 就好了...
(没有试过,仅供参考)
tyrantZhao
2020-01-29 10:26:16 +08:00
好像没有相关的 api
las917vki
2020-01-29 10:34:37 +08:00
@ysc3839 没错的咯,这些 API 本来就是为了配合调试器使用了,我本意就说了,正常的程序不应该使用这些 API。
这些 API 的设计本质上是为了让外部的程序(调试器什么的)可以 Attach 上去控制一个线程的 CONTEXT,配合诸如 SetThreadContext 这种当年他们拿来玩乐的 API 做当年那些 hack 喜欢做的事情。本质上这些都是 Win32 调试 API 的扩展。
crclz
2020-01-29 10:36:08 +08:00
.NetCore c# 已经不支持 Thread.Abort 方法了。这就意味着应该采用线程主动停止运行的方式。
wanguorui123
2020-01-29 12:25:44 +08:00
while(true){
sleep(1)
}
nyanyh
2020-01-29 14:13:29 +08:00
@wanguorui123 #17 这是在线程内部控制了
funnuy
2020-01-29 17:43:59 +08:00
ptrace

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/640659

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX