V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
nyanyh
V2EX  ›  Linux

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

  •  
  •   nyanyh · 2020-01-28 17:39:40 +08:00 · 5906 次点击
    这是一个创建于 1762 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    while(true){}
    
    19 条回复    2020-01-29 17:43:59 +08:00
    ipwx
        1
    ipwx  
       2020-01-28 17:43:05 +08:00 via Android
    标准 posix 没有吧。但是 sleep 以及所有系统的 io 调用都是可以打断的应该
    nyanyh
        2
    nyanyh  
    OP
       2020-01-28 17:46:06 +08:00
    @ipwx #1 单纯一个 while(true)空循环,这种线程没办法从外部打断呀
    我想了个 trick,如果能在指定线程 context 下执行代码(类似 Windows 下的 APC ),然后上个 pthread_cond 应该可以实现我的效果,但是我也没有找到 Linux 下怎么在另一个 context 下执行代码的方法
    CismonX
        3
    CismonX  
       2020-01-28 17:56:17 +08:00
    标准 posix 的话,可以用 pthread_sigmask + sigwait + pthread_kill 来暂停线程,signal handler 是必不可少的
    712e1959
        4
    712e1959  
       2020-01-28 18:15:59 +08:00 via Android
    ^z
    ?
    nyanyh
        5
    nyanyh  
    OP
       2020-01-28 18:36:25 +08:00
    @CismonX #3 pthread_sigmask 要在线程内调用,线程外不行
    nyanyh
        6
    nyanyh  
    OP
       2020-01-28 18:36:48 +08:00
    @712e1959 #4 ^z 发送的 SIGTSTP,会暂停整个进程
    ipwx
        7
    ipwx  
       2020-01-28 20:12:24 +08:00
    @nyanyh 我觉得你不必纠结这个问题。一个好的多线程程序一般不依赖这种外部 suspend 来结束线程,因为这容易导致线程没清理干净资源。还是应该有个协调退出的机制。
    nightwitch
        8
    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
        9
    las917vki  
       2020-01-28 22:49:28 +08:00 via iPhone
    Windows 这些操作其他线程、进程上下文的 API 是十分粗暴和低级的…
    而且当年添加这些 API 本质上是为了适应 Win32 程序一些乱七八糟的设计问题…( UI 上
    正常的程序员都应该使用标准的 wake 和 wait 成对来操作。
    monsterxx03
        10
    monsterxx03  
       2020-01-28 23:03:40 +08:00
    PTRACE_ATTACH
    ysc3839
        11
    ysc3839  
       2020-01-29 03:10:33 +08:00 via Android
    @las917vki 那 macOS 为什么也有呢?
    ysc3839
        12
    ysc3839  
       2020-01-29 03:12:32 +08:00 via Android
    @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
        13
    lqf96  
       2020-01-29 07:26:07 +08:00
    @nyanyh 突发奇想,cgroup freezer 不知道有没有用,当然这个肯定只有 linux 有...之后就好办了,读写内存就用 process_vm_readv 和 process_vm_writev 就好了...
    (没有试过,仅供参考)
    tyrantZhao
        14
    tyrantZhao  
       2020-01-29 10:26:16 +08:00
    好像没有相关的 api
    las917vki
        15
    las917vki  
       2020-01-29 10:34:37 +08:00   ❤️ 1
    @ysc3839 没错的咯,这些 API 本来就是为了配合调试器使用了,我本意就说了,正常的程序不应该使用这些 API。
    这些 API 的设计本质上是为了让外部的程序(调试器什么的)可以 Attach 上去控制一个线程的 CONTEXT,配合诸如 SetThreadContext 这种当年他们拿来玩乐的 API 做当年那些 hack 喜欢做的事情。本质上这些都是 Win32 调试 API 的扩展。
    crclz
        16
    crclz  
       2020-01-29 10:36:08 +08:00
    .NetCore c# 已经不支持 Thread.Abort 方法了。这就意味着应该采用线程主动停止运行的方式。
    wanguorui123
        17
    wanguorui123  
       2020-01-29 12:25:44 +08:00
    while(true){
    sleep(1)
    }
    nyanyh
        18
    nyanyh  
    OP
       2020-01-29 14:13:29 +08:00
    @wanguorui123 #17 这是在线程内部控制了
    funnuy
        19
    funnuy  
       2020-01-29 17:43:59 +08:00 via iPhone
    ptrace
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2821 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 00:37 · PVG 08:37 · LAX 16:37 · JFK 19:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.