繁体   English   中英

如何解决忙等待许多正在运行的线程

[英]how to solve busy waiting for many running threads

我写了一个多线程程序:

#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <fstream>
#include <iostream>
using namespace std;
ofstream myfile;
BYTE lockmem=0x0;
unsigned int __stdcall mythreadA(void* data) 
{
    __asm
    {
        mov DL,0xFF
        mutex:
        mov AL,0x0
        LOCK CMPXCHG lockmem,DL
        jnz mutex
    }

    // Enter Critical Section
    for (int i = 0; i < 100000; i++) 
    {
        myfile << "." << i << endl;
    }
    // Exit Critical Section
    __asm
    {
    lock not lockmem
    }
    return 0;
}

int main(int argc, char* argv[])
{
    myfile.open ("report.txt");
    HANDLE myhandleA[10];
    //int index = 0;
    for(int index = 0;index < 100;index++)
    {
        myhandleA[index] = (HANDLE)_beginthreadex(0, 0, &mythreadA, 0, 0, 0);
    }
    getchar();
    myfile.close();
    return 0;
}

在关键部分,我编写内联代码,以确保只有一个线程在临界区。(在这个程序中,我不想使用API​​和函数来实现临界区中唯一的一个线程,所以我使用内联汇编)。 现在我忙着等待问题。因为在一个线程进入临界区之后,其他线程在关键部分之前忙于循环,所以cpu的进程上升了! 在这里,我寻找解决忙碌等待问题的方法。 (我更喜欢使用汇编指令而不是API和任何函数,但我也想知道它们)

你在做什么基本上叫做自旋锁,它不应该用于长时间的操作。 如您所述,这是消耗CPU时间的预期结果。

但是,您可以基于自旋锁和condvar / event构建互斥锁(futex)(快速用户模式互斥锁)。

您可以使用阻止必须等待的线程的内核API调用,或者您可以浪费CPU周期和内存带宽来保持您的风扇全速运行并使办公室保持温暖。

没有任何其他选择。

如果我理解你的问题和程序正确,你的程序中有几个问题。 其他人也在上面的帖子中提到过这一点。

  • 您的实际关键部分代码非常慢,因为您在文件的新行中写入数字达100000次。 文件I / O操作将非常慢,在您的情况下,这是您的线程函数正在执行的操作。 我不太了解您在程序中使用的汇编指令,但看起来这些锁定机制代码正在为剩余的线程创建繁忙的等待代码,这些代码尚未安排执行。 如上所述,您应该开始使用基于Microsoft的系统上提供的EnterCriticalSection()和LeaveCriticalSection()API。 这些API在内部处理任何事情(一般不能从我们自己的逻辑中实现),因此在等待时不会有任何CPU峰值。

  • 如果您仍想使用当前逻辑执行某些操作,我认为您应该使用/实现某种形式的sleep()类型函数,该函数应该执行并尝试。 这将确保由于连续执行/检查某些标志而不会有任何CPU忙时间情况。

  • Calvin还提到你应该尝试分配锁而不是中央锁。 我们应该记住一件事,如果我们的任务很简单并且可以通过传统的单线程方法轻松完成,我们就不应该采用多线程解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM