【问题标题】:Semaphore (Mutex) trouble信号量(互斥)麻烦
【发布时间】:2012-05-01 15:10:43
【问题描述】:

假设我有一个互斥锁、两个线程、一个函数和一个循环(伪代码)。 功能:

void Update(){
    Mutex.enter();
    ...// time: 10 ms
    Mutex.leave();
}

Main.cpp:

void main(){
    ...// Starting thread
    while(true)
        Update();
}

线程:

void Thread(void *){
    Mutex.enter();
    ... // 
    Mutex.leave();
}

但是Function调用不断,所以Mutex小时间是空闲的。线程进入 Mutex 的机会有多大?如果低,如何解决?

【问题讨论】:

  • 也许在更新调用之间显式地让出处理器?例如有pthread_yield()函数
  • 您应该非常非常努力地为您的数据/代码找到一些其他设计,以消除持续调用。 Yield() 是子弹伤口上的绷带。这可能会有所帮助,但您很快就会需要手术。
  • 当线程调用 Mutex.enter 时,它会阻塞,一旦其他线程调用离开,线程应该获取互斥锁,因为它是当时唯一请求它的线程。
  • 只需删除Thread 功能。没有它,代码将取得与使用它一样多的进步。如果Update 没有做你想做的工作,你应该修复它。如果是,那么Thread 在您的代码中添加了什么?

标签: c++ multithreading mutex semaphore


【解决方案1】:

如果您使用的是 boost 线程 (link),那么我会使用 yield()。它将允许任何其他“等待”线程“有机会”运行。

也可能有一种 win32 或 pthreads 方式来执行此操作。

编辑:顺便说一下,使用yield() 在锁之外。如果它在锁里面,那显然是没用的。

Edit2:这里是不同平台的功能:

  • Win32:SwitchToThread()msdn link
  • Linux/Unix pthreads: `pthread_yield()' link

如果您不在这些平台上,请阅读这些链接上的说明,并在您的框架中寻找一个功能相同的功能。

【讨论】:

  • 不,我没有使用 boost 和其他库。
  • yield 确实是需要做的,概念不限于boost。无论您使用什么线程库,都必须有一个函数。喜欢 pthread_yield
  • 那你用什么?赢32? Unix pthreads?请向我们提供有关您的编译器/环境的信息。
  • @WORLD_DYNAMIC_USER - 使用我上面链接的 Win32 函数,SwitchToThread()。我什至在其中包含了 msdn 链接以获得更大的解释。
  • 高速调用 yield 会对系统性能产生严重的负面影响。它主要是为了允许中断运行时间较长的高优先级任务。
【解决方案2】:

从您展示的伪代码看来,线程之间似乎没有合作。如果 thread2 幸运地在调用第一个 Update() 之前获取了互斥锁,那么在 thread2 的整个生命周期内不会调用 Update() 函数。对我来说,它看起来像是一个有缺陷的设计。如果 thread2 正在做这项工作,并且“主”线程正在调用 Update() 函数来监视和报告 thread2 线程例程中发生的任何事情的进度,那么让 thread1(主线程)等待更有意义update_required 信号和线程 2(正在进行工作的那个)将完成工作,然后用报告进度所需的所有数据填充结构变量,并发出信号 thread1 使用数据并报告进度。使用这种结构变量的环形缓冲区可以完全消除对互斥体的需求。

【讨论】:

    猜你喜欢
    • 2017-08-24
    • 2011-04-20
    • 2012-09-01
    • 2011-01-05
    • 2011-04-10
    • 1970-01-01
    • 2014-04-28
    • 1970-01-01
    相关资源
    最近更新 更多