简体   繁体   English

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

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

I have write a multithread program : 我写了一个多线程程序:

#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;
}

at the critical section I write inline code to sure that only one thread is in the critical section .( in this program I don't want to use API and functions for implement the only one thread in critical section so I use inline assembly ). 在关键部分,我编写内联代码,以确保只有一个线程在临界区。(在这个程序中,我不想使用API​​和函数来实现临界区中唯一的一个线程,所以我使用内联汇编)。 now I have busy waiting problem .because after one thread enter in the critical section the other threads are busy in the loop before critical section , so the process of cpu go up and up! 现在我忙着等待问题。因为在一个线程进入临界区之后,其他线程在关键部分之前忙于循环,所以cpu的进程上升了! here I search for ways to solve the problem of busy waiting. 在这里,我寻找解决忙碌等待问题的方法。 ( I prefer to use assembly instruction instead of API and any functions but I also want to know them) (我更喜欢使用汇编指令而不是API和任何函数,但我也想知道它们)

What you are doing is basically called spinlock, and it should not be used for long operations. 你在做什么基本上叫做自旋锁,它不应该用于长时间的操作。 It is the expected result to drain cpu time as you described. 如您所述,这是消耗CPU时间的预期结果。

You may however build a mutex, of futex (fast user-mode mutex) based on spinlock and condvar/event. 但是,您可以基于自旋锁和condvar / event构建互斥锁(futex)(快速用户模式互斥锁)。

You can use a kernal API call that blocks the threads that must wait, or you can waste CPU cycles and memory-bandwidth keeping your fans at full speed and your office warm. 您可以使用阻止必须等待的线程的内核API调用,或者您可以浪费CPU周期和内存带宽来保持您的风扇全速运行并使办公室保持温暖。

There isn't any other choice. 没有任何其他选择。

If I understand your question and program correctly,there are couple of problem in your program. 如果我理解你的问题和程序正确,你的程序中有几个问题。 This is mentioned by others as well in above post. 其他人也在上面的帖子中提到过这一点。

  • Your actual critical section part of code is terribly slow as your are writing the numbers in new line in your file for 100000 times. 您的实际关键部分代码非常慢,因为您在文件的新行中写入数字达100000次。 The file I/O operation would be very very slow and in your case this is what your thread function is each doing. 文件I / O操作将非常慢,在您的情况下,这是您的线程函数正在执行的操作。 I am not aware much about the assembly instruction used by you in your program but its looks like that these locking mechanism code are creating busy waiting code for your remaining threads which is yet to be scheduled for execution. 我不太了解您在程序中使用的汇编指令,但看起来这些锁定机制代码正在为剩余的线程创建繁忙的等待代码,这些代码尚未安排执行。 As mentioned above you should start using the EnterCriticalSection() and LeaveCriticalSection() API provided on Microsoft based system. 如上所述,您应该开始使用基于Microsoft的系统上提供的EnterCriticalSection()和LeaveCriticalSection()API。 These API internally take care about anything(which can not be achieved in general from our own logic) and hence you would not have any CPU spikes while waiting. 这些API在内部处理任何事情(一般不能从我们自己的逻辑中实现),因此在等待时不会有任何CPU峰值。

  • If you still want to do something using your current logic, I think you should use/implement some form of sleep() type function which should be executed and try. 如果您仍想使用当前逻辑执行某些操作,我认为您应该使用/实现某种形式的sleep()类型函数,该函数应该执行并尝试。 This would ensure that there would not be any CPU busy time scenario due to continuous execution/check for some flag. 这将确保由于连续执行/检查某些标志而不会有任何CPU忙时间情况。

  • Calvin has also mentioned that you should try to distribute the locks instead of central lock. Calvin还提到你应该尝试分配锁而不是中央锁。 We should remember one thing, if our task is simple and can be done easily by conventional single thread approach,we should not go for multi-threaded solution. 我们应该记住一件事,如果我们的任务很简单并且可以通过传统的单线程方法轻松完成,我们就不应该采用多线程解决方案。

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

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