技术解析

Linux 下有暂停线程执行的 API 吗?
0
2021-06-18 20:44:20
idczone

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

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

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

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

while(true){}

标准 posix 没有吧。但是 sleep 以及所有系统的 io 调用都是可以打断的应该

单纯一个 while(true)空循环,这种线程没办法从外部打断呀
我想了个 trick,如果能在指定线程 context 下执行代码(类似 Windows 下的 APC ),然后上个 pthread_cond 应该可以实现我的效果,但是我也没有找到 Linux 下怎么在另一个 context 下执行代码的方法

标准 posix 的话,可以用 pthread_sigmask + sigwait + pthread_kill 来暂停线程,signal handler 是必不可少的

^z
?

pthread_sigmask 要在线程内调用,线程外不行

^z 发送的 SIGTSTP,会暂停整个进程

我觉得你不必纠结这个问题。一个好的多线程程序一般不依赖这种外部 suspend 来结束线程,因为这容易导致线程没清理干净资源。还是应该有个协调退出的机制。

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。
使用信号会带来一些其他问题,比如外部给进程发信号,内核会地送到任意没有阻塞该信号的线程,可能会导致意料之外的线程睡眠 /唤醒。

Windows 这些操作其他线程、进程上下文的 API 是十分粗暴和低级的…
而且当年添加这些 API 本质上是为了适应 Win32 程序一些乱七八糟的设计问题…( UI 上
正常的程序员都应该使用标准的 wake 和 wait 成对来操作。

PTRACE_ATTACH

那 macOS 为什么也有呢?

而且据微软文档所说 https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-suspendthreadThis function is primarily designed for use by debuggers.

突发奇想,cgroup freezer 不知道有没有用,当然这个肯定只有 linux 有...之后就好办了,读写内存就用 process_vm_readv 和 process_vm_writev 就好了...
(没有试过,仅供参考)

好像没有相关的 api

没错的咯,这些 API 本来就是为了配合调试器使用了,我本意就说了,正常的程序不应该使用这些 API。
这些 API 的设计本质上是为了让外部的程序(调试器什么的)可以 Attach 上去控制一个线程的 CONTEXT,配合诸如 SetThreadContext 这种当年他们拿来玩乐的 API 做当年那些 hack 喜欢做的事情。本质上这些都是 Win32 调试 API 的扩展。

.NetCore c已经不支持 Thread.Abort 方法了。这就意味着应该采用线程主动停止运行的方式。

while(true){
sleep(1)
}

这是在线程内部控制了

ptrace

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服