【问题标题】:Using Critical Sections/Semaphores in C++在 C++ 中使用临界区/信号量
【发布时间】:2013-04-25 10:04:06
【问题描述】:

我最近开始使用 C++ 而不是 Delphi。 有些事情似乎完全不同。 例如,我不知道如何初始化 Semaphores 和 CriticalSections 等变量。 到目前为止,我只知道两种可能的方法: 1. 在构造函数中初始化临界区是愚蠢的,因为每个实例都将使用自己的临界区而不同步任何东西,对吧? 2. 使用全局变量并在创建表单时对其进行初始化似乎也不是完美的解决方案。 谁能告诉我如何做到这一点?

我需要的关键部分只是一个简短的解释: 我想从不同的线程中填充一个 ListBox。 信号量: 不同的线程正在移动鼠标,这不应该被打断。

谢谢!

【问题讨论】:

  • 标准 C++ 仅在 <mutex><condition_variable> 中分别使用互斥锁和条件变量作为同步机制。你可以从那里build your own semaphore
  • 所以问题不是如何初始化你的对象,而是在哪里,对吧?如果是这样,出于好奇,您在 Delphi 中是在哪里做的?
  • Delphi 提供了关键字初始化和终结,这使得 imo 更容易
  • 对了,我忘了。答案即将到来……;)

标签: c++ initialization semaphore critical-section


【解决方案1】:

与 Delphi 不同,C++ 没有单元初始化/终结的概念(但您已经发现了这一点)。

我们剩下的很少。你需要区分两件事:

  • 在哪里声明变量(全局、静态类成员、类成员、函数本地、函数中的静态——我想这涵盖了所有内容)
  • 初始化变量的位置(由于您关心 C API,您必须自己调用初始化函数)

事实是,在你的情况下,你在哪里声明你的变量并不重要,只要你的程序的所有其他需要它的部分都可以访问它,并且唯一的要求是你在哪里应该初始化它是:在你真正开始使用它之前(这意味着,在你启动其他线程之前)。

在你的情况下,我可能会使用singleton pattern。但是 C++ 就是这样,单例在初始化期间会受到竞争条件的影响,没有干净的方法可以解决这个问题。因此,除了您的单例之外,您还应该确保在开始在多线程上下文中使用它之前正确创建它。在main() 的开头简单地调用getInstance() 就可以解决问题(或您认为合适的任何其他地方)。如您所见,这只关心您声明变量的位置,而不是您初始化它的位置,但不幸的是,C++ 在多线程方面存在重要限制(它在-specified) 所以没有办法解决这个问题。

总结一下:做你想做的事(只要它有效),别再担心了。

【讨论】:

    【解决方案2】:

    在我看来,您只需要一个关键部分来同步来自各个线程的列表框的更新。鼠标将继续移动。信号量不适合解决方案。您在类构造函数中初始化临界区。列表框在哪里。编写一个更新列表框的方法。

    //psudo code
    UpdateListBox()
    {
     //enter critical section
     //update
     //leave critical section
    }
    

    所有线程都会调用这个方法来更新列表框。

    关于临界区的信息在这里 http://msdn.microsoft.com/en-us/library/windows/desktop/ms683472%28v=vs.85%29.aspx

    【讨论】:

    • 我假设你是在 Windows 机器上开发它
    • 如果我必须在类构造函数中初始化它,是否意味着我必须使用全局变量并在其他单元中使用外部关键字?
    • 它不必是全局的。把它放在任何地方。就是这样,您必须将其作为参数传递给 entercriticalsection 和 releasecriticalsection。
    猜你喜欢
    • 1970-01-01
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-12
    • 2015-04-21
    • 1970-01-01
    相关资源
    最近更新 更多