【问题标题】:Prevent user-mode APCs from user mode防止用户模式 ​​APC 进入用户模式
【发布时间】:2019-02-18 20:34:41
【问题描述】:

内核模式代码可以prevent some or all asynchronous procedure calls (APCs) by entering a critical or guarded region or by Raising the current IRQL。这样,就可以在不受 APC 干扰的情况下执行包含警报等待的代码。

用户模式代码是否有类似的方法(暂时)禁用当前线程中的用户模式 ​​APC?


对于托管和非托管代码的答案,我很高兴。我已经验证了以下方法不起作用

  • 临界区 (EnterCriticalSection/LeaveCriticalSection)
  • stdlib 互斥体 (std::mutex, std::recursive_mutex, ...)
  • 托管同步功能(lock 语句、MethodImpl(MethodImplOptions.Synchronized) 注释)

【问题讨论】:

  • 你的意思是阻止用户模式 ​​APC 在当前线程、特定的其他线程、进程中的任何线程(包括尚未创建的线程)或所有进程当前登录会话?
  • (请注意,您所说的关于内核模式的所有内容只是防止 APC 中断当前线程,它们仍然可以在其他线程上运行)
  • 用户 APC 仅在线程进入警报状态时运行。所以不要进入警报状态。
  • @RaymondChen:这对于本机代码来说已经足够了,但当托管运行时与您的线程玩非自愿的上下文切换游戏时可能很难实现(例如,.NET 垃圾收集或Thread.Abort ) 这些在某种意义上可以被视为用户模式异步调用,即使它们不是 OS APC。
  • 对我来说听起来像是XY Problem。你最终想要完成什么?为什么您认为防止 APC 是解决方案的一部分?

标签: c# c++ windows winapi


【解决方案1】:

否。防止用户模式 ​​APC 发生的唯一选项是:

  • 首先不调度 APC
  • 不执行警报等待
  • 在另一个线程上调度 APC
  • 将所有可警报等待移动到另一个没有安排 APC 或首先不允许可警报等待的线程

    QueueUserWorkItem 似乎是不错的候选者,当使用 WT_EXECUTEDEFAULT 时:

    回调函数排队到 [...] 无法执行警报等待的线程。

(感谢RbMm 确保在 cmets 中没有用于禁用 APC 的用户模式 ​​API)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 2019-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-18
    相关资源
    最近更新 更多