【问题标题】:Putting a thread to sleep (c pthreads)使线程进入睡眠状态(c pthreads)
【发布时间】:2012-06-21 20:01:09
【问题描述】:

我正在使用 pthreads 并试图让线程休眠 X 秒。

我试过sleep()nanosleep()pthread_cond_timedwait()(等待一个假的互斥锁X秒),pthread_yield(),每次线程唤醒时检查时间,看看是否该运行,最后只是忙着等待 X 秒。

问题在于,尽管考虑到结果,所有这些方法都可以正常工作,但它们并没有给出我期望的性能结果。性能以吞吐量(每秒回复)而不是时间来衡量。

在我的配置中,我在 2 个模拟物理内核(运行 Ubuntu Server 的 VirtualBox)上运行 3 个软件线程。我希望在将 3 个线程中的 1 个置于睡眠状态时获得更好的性能,因为其他 2 个线程有一个专用的 physical 核心可以在其上运行。然而,我得到了完全相反的行为(我所有的方法):增加睡眠时间会降低性能。 (注意 sleeping 线程的工作负载是 130-300ms。)

可能是因为虚拟化(主机有 4 个核心)?可能是因为我使用的方法与我使用 pthread_yield 的方法类似吗?

sleep()nanosleep() 是如何实现的?他们使用信号吗?您认为使用信号处理程序和alarm() 的实现会是更好的方法吗?当我拨打pthread_cond_wait() 时会发生什么?它是如何实现的?

我也尝试使用chrt 更改调度策略,但没有成功。

【问题讨论】:

  • 为什么不使用互斥体或信号量?让线程只在需要的时候休眠
  • 您能否提供示例代码以及实际性能数据(例如,来自time 命令)来证明您的问题?
  • 您的线程执行了多少工作?你睡多久?多常?不要忘记上下文切换会占用宝贵的 CPU 周期。
  • @Jarry 我将如何将互斥锁或信号量保持 X 秒?你能举个例子说明你的想法吗?
  • 抱歉,您从未在问题中定义“性能”和“结果”的含义。在您定义要衡量的确切数量以确定性能之前,对于“我如何提高性能”没有真正的答案。

标签: c multithreading pthreads


【解决方案1】:
  1. 通过分析器运行您的代码以查看时间花在了哪里。否则,您只会猜测,根据我的经验,这些猜测 90% 的时间都是错误的。

  2. alarm() 可能会有所帮助,但它实际上应该做 sleep() 所做的事情,所以我真的不希望有什么不同。

以下是一些可能导致此问题的想法:

  • 缓存刷新。如果您的两个工作线程很好地使用了缓存,那么切换到新线程可能意味着缓存刷新,这可能非常昂贵。这里的想法是,如果睡眠者让它们保持更长的时间,工作线程可以填充更多缓存。

  • 两个工作线程需要睡眠者占用/锁定的资源。

  • 您衡量性能的效果如何?也许您测量了其他一些影响(桌面搜索索引您的计算机等)

要深入了解这一点,您必须逐个函数地减少代码,直到所需的行为开始出现 + 在分析器中运行以检查意外情况。

【讨论】:

    【解决方案2】:

    我同意@Aaron Digulla 的观点,即通过反复试验和猜测,您永远无法得到性能问题的答案。 但更重要的是,我不确定你测量的是正确的东西,至少按照你的说法,你的周期性线程之间的睡眠时间越长,你的吞吐量就越差。按照这个逻辑,您可以将睡眠周期设置为无限数(基本上大于您的测量周期),并且您的吞吐量应该是最差的。是这样吗?

    请注意,衡量服务器吞吐量可能是一项棘手的业务,在衡量和客户端设置方面存在许多缺陷。以下是一些示例,说明您的综合基准数字很容易被欺骗:http://www.teamquest.com/pdfs/whitepaper/load-test.pdf

    如果您对性能测量感兴趣,请阅读该文章。是纯金的。

    【讨论】:

    • 是的,就是这样。现在关于测量,我对我的测量技术很有信心,尽管我不是服务器专家。我还将阅读您的参考资料,看看是否有任何可能与我的案例相关的内容,我希望发现它和您说的一样有益:)。
    • 好吧,如果是这种情况,我认为您将不得不开始减少变量。您能否在真实的物理多核机器上运行相同的测试(这样虚拟机的东西就不在等式了)。此外,另一件值得做的事情是将工作线程的数量从 2 个增加,并查看它的吞吐量。
    • 不幸的是,在物理多核上运行是不可能的,也是不可取的。我发现使用线程数是一个非常好的主意,但我不知道为什么我还没有尝试过。如果有什么有趣的事情发生,我会告诉你的。
    • 实际上增加软件线程的数量 (4-8) 确实隐藏了差异(将更长睡眠的最低数字提高到与完全不睡眠相同)。然而,应用程序仍然没有从睡眠线程中受益。使用更多的线程也无济于事,如果你足够大,它就会开始给出初始图片。
    • 因此,如果不详细检查代码,我认为您的睡眠线程实际上正在做一些有助于吞吐量的有用工作(除了定期的簿记工作类型)。并且可能存在一些阻塞操作(从磁盘/网络等读取),这意味着您需要比 num_cpus 更多的线程来保持 cpus 忙碌。
    猜你喜欢
    • 1970-01-01
    • 2012-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    • 2011-09-08
    • 2011-09-05
    相关资源
    最近更新 更多