【问题标题】:Critical sections better in thread or main program?线程或主程序中的关键部分更好?
【发布时间】:2011-02-17 23:26:03
【问题描述】:

我曾经在访问共享数据时使用临界区(在 C++ 中)来阻止线程执行,但是为了工作,它们必须等到数据没有被使用后再阻塞,也许在主线程或线程中使用它们会更好。 那么如果我希望我的主程序具有优先权并且不被阻塞,我必须使用它内部的临界区来阻塞其他线程还是相反?

【问题讨论】:

  • boost、pthread 或 Win32 临界区? c++ 还没有临界区,所以请确定目标,并适当地重新标记。
  • @mzabsky:客观地说,这种说法似乎并不正确。 :)

标签: c++ critical-section


【解决方案1】:

您似乎对什么是关键部分以及它们如何工作有相当的误解。

一般来说,临界区 (CS) 是需要“独占”运行的一段代码——即,您需要确保在任何给定时间只有一个线程在执行该段代码。

正如在大多数环境中使用的术语一样,CS 实际上是一个互斥体——互斥信号量(也称为二进制信号量)。它是一种数据结构(和一组函数),用于确保一段代码被独占执行(而不是引用代码本身)。

在任何情况下,CS 仅在/如果您有一些将在多个线程中执行的代码时才有意义,并且您需要确保它在任何给定时间仅在一个线程中执行。这通常是当您拥有一些共享数据时,如果多个线程一次尝试操作它,这些数据可能并且将会被破坏。当/如果出现这种情况,您需要为 每个 处理该数据的线程“使用”临界区,以确保共享数据不会损坏。

确保特定线程保持响应是一个完全独立的问题。在大多数情况下,这意味着使用队列(一种可能性)允许线程快速将任务“移交”给其他线程,而竞争最小(即,在处理数据期间不使用 CS, CS 只能持续足够长的时间来将数据结构放入队列中,而其他一些线程会从那里进行处理)。

【讨论】:

  • 那么...如果我的主循环使用 var A 并且我需要一个线程来使用 A 在使用 A 时进入线程中的关键部分还不够,因为在使用时主循环可能已被阻塞一个?
  • 如果两个线程都在操作 A,那么在这样做之前,两个线程(可能)都需要进入临界区。如果他们都大量使用 A,那么您很有可能会遇到很差的响应时间。
  • 好的,很清楚...只是为了确定,仅仅读取变量不需要它?
  • @Greg2fs:是的,如果您只读取变量,则不需要互斥体/CS。
  • 好的,谢谢。我不知道我是否在滥用我可能会打开一个新话题,我的程序有问题,事实上,如果我不使用线程,程序可以完美运行,但它在两个都可以在 Visual Studio 中运行仅通过启动 exe 来发布和调试但不在 VS 之外,似乎有些线程在没有完成工作的情况下正在退出,我该如何调试?
【解决方案2】:

你不能说“我在线程 A 中使用了临界区,但不在线程 B 中”。临界区是一段访问共享资源的代码。当此代码从两个并行运行的线程执行时,共享资源可能会损坏,因此您需要同步对它的访问:您需要使用一些同步对象(互斥锁、信号量、事件......取决于平台和您正在使用的 API)。 ThreadA 锁定了临界区,因此 ThreadB 需要等到 ThreadA 释放它。

如果您希望您的主线程阻塞(等待)少于工作线程,请将工作线程优先级设置为低于主线程的优先级。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-14
    • 2011-01-29
    相关资源
    最近更新 更多