V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dangyuluo
V2EX  ›  C++

Condition variable 是怎么告诉调度器这个线程不应该被调度,又是怎样唤醒的呢?

  •  
  •   dangyuluo · 2020-09-08 20:39:44 +08:00 · 1736 次点击
    这是一个创建于 1529 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近工作中发现了一个 Bug,就是有一个 condition variable 在临界区内调用了notify_one,让另一个在cv.wait的线程唤醒了一下然后立马又被 blocked 了。虽然不影响逻辑,但是会带来额外的线程切换负担。

    公司的大神说: You shouldn't notify_one() while holding the mutex.

    虽然问题解决了(通过lock.unlock(); cv.notify_one(); lock.lock();),但是这引起了我好奇,cv.wait是如何告诉调度器本线程不应该被调度的?又是怎样在得到信号后唤醒线程的?

    请高人帮忙解答一下吧,谢谢!

    3 条回复    2020-09-09 16:05:52 +08:00
    ysc3839
        1
    ysc3839  
       2020-09-08 21:03:04 +08:00   ❤️ 1
    Windows 下 cv.wait 估计是调用 SleepConditionVariableSRW,可以参考一下 ReactOS 的实现 https://doxygen.reactos.org/da/d99/condvar_8c_source.html
    RtlSleepConditionVariableSRW 是直接调用 InternalSleep 的,而 InternalSleep 则是通过调用 NtWaitForKeyedEvent 来等待的,结论是用了内核提供的机制。

    Linux 下 cv.wait 估计是调用 pthread_cond_wait,可以参考各类 pthread 的实现,为了代码更加简单,这里选择参考 musl (下面的 GitHub 仓库是一个非官方的 musl mirror,用 GitHub 只是为了方便搜索)
    pthread_cond_wait 是直接调用 pthread_cond_timedwait 的 https://github.com/ifduyue/musl/blob/0b0640219338b80cf47026d1970b5503414ed7f3/src/thread/pthread_cond_wait.c
    pthread_cond_timedwait 是通过 __timedwait_cp 来等待的 https://github.com/ifduyue/musl/blob/0b0640219338b80cf47026d1970b5503414ed7f3/src/thread/pthread_cond_timedwait.c#L100
    而 __timedwait_cp 则是通过 futex syscall 来等待的 https://github.com/ifduyue/musl/blob/0b0640219338b80cf47026d1970b5503414ed7f3/src/thread/__timedwait.c#L52
    结论也是用了内核提供的机制。
    dangyuluo
        2
    dangyuluo  
    OP
       2020-09-08 21:22:00 +08:00
    @ysc3839 谢谢 非常有帮助
    codehz
        3
    codehz  
       2020-09-09 16:05:52 +08:00
    建议直接看正确用法,具体实现是有可能发生变化的(所以不能依赖底层的行为
    https://zh.cppreference.com/w/cpp/thread/condition_variable
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1200 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 18:35 · PVG 02:35 · LAX 10:35 · JFK 13:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.