hmmmmmm
hmmmmmm

Reputation: 67

Calling a method in another thread after a thread is finished

I'm trying to parallelize my program, but since I'm very new to threads, I'm facing some problems.

I have two methods which are part of the same class. One of the methods does some calculations in a for loop and pushes the results in a vector, other method (runTheResult) takes the vector and launches a thread using the obtained vector. I wish to launch another thread for running the next obtained result every time runTheResult is done with a result while limiting the maximum number of threads at a time to 4.

The structure of my program is like:

void runTheResult(vector<double>& u){

//process 'u' and launch a thread 


};

void method(){

for(...){

//calculate

    for(...){

    //put the calculations in vector<double>result

    };

    runTheResult(result); 

};

};

I've googled about this a lot and one of the solutions is to maintain a message que. The problem with this, however, is if I implement a que, I'll have to check the que with another thread periodically in a while loop. If I use while loop like while(true){//check for new messages if number of threads is less than five}, I'll lose a lot of processing power and if I choose to put the loop to sleep if condition is not met, I waste processing power. The functions I'm running in threads take 2-5 seconds each and I've to process ~1k to 50k of them so even a second of delay per loop is a lot.

Is it possible to run runTheResultin another thread every time runTheResult is done? or is there better way to do this?

Upvotes: 0

Views: 905

Answers (1)

Israel dela Cruz
Israel dela Cruz

Reputation: 806

Others are telling you to use message queue because that's the safest way to do it. Your program must have at least a main thread that the user(you or end-user) can interact with. This main thread will be looping for as long as your program runs. You do your message processing here

// this is not actually running the result now
// this only sends it to the main thread that will run the result
void runTheResult(vector<double>& u){ 

    //process 'u' and launch a thread. 
    // @NOTE Launching a thread again will not be beneficial as it will still be blocked 
    // by the mutex

    // convert/store vector into Message. To make it usable for other types
    // or you can just change Message to double
    Message u_message = to_message(u)

    std::lock_guard<std::mutex> lock(message_mutex);
    messages_shared.append(u_message);

};

void method() // runs on worker thread
{
    for(...){

    //put the calculations in vector<double>result

    };

    runTheResult(result);
}

void getMessages_safe(std::vector<Messages>& outMessages_safe)
{
    // as Ted Lyngo suggests, using lock_guard is best practice. See edit for alternative
    std::lock_guard<std::mutex> lock(message_mutex);
    outMessages_safe = messages_shared;
    messages_shared.clear();
}

std::vector<Message> messages_shared;
std::mutex message_mutex;

void main() { // this runs on the very first thread of the program
  while (isProgramRunning)
  {
      std::vector<Message> messages_safe; // safe to access by this thread only
      getMessages_safe(messages_safe);

      // dispatch messages to whoever needs it

      // launch worker thread
  }
}

Upvotes: 1

Related Questions