简体   繁体   中英

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 ). 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! 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)

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.

You may however build a mutex, of futex (fast user-mode mutex) based on spinlock and condvar/event.

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.

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. The file I/O operation would be very very slow and in your case this is what your thread function is each doing. 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. 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.

  • 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. This would ensure that there would not be any CPU busy time scenario due to continuous execution/check for some flag.

  • Calvin has also mentioned that you should try to distribute the locks instead of central lock. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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