Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(C++ Threads): Creating worker threads that will be listening to jobs and executing them concurrently when wanted

Suppose we have two workers. Each worker has an id of 0 and 1. Also suppose that we have jobs arriving all the time, each job has also an identifier 0 or 1 which specifies which worker will have to do this job.

I would like to create 2 threads that are initially locked, and then when two jobs arrive, unlock them, each of them does their job and then lock them again until other jobs arrive.

I have the following code:

  #include <iostream>
  #include <thread>
  #include <mutex>

  using namespace std;

  struct job{

      thread jobThread;
      mutex jobMutex;

  };

  job jobs[2];


  void executeJob(int worker){

      while(true){

          jobs[worker].jobMutex.lock();

          //do some job

      }

   }

  void initialize(){

      int i;
      for(i=0;i<2;i++){
                jobs[i].jobThread = thread(executeJob, i);
      }

   }

  int main(void){

      //initialization
      initialize();

      int buffer[2];
      int bufferSize = 0;

      while(true){
          //jobs arrive here constantly, 
            //once the buffer becomes full, 
            //we unlock the threads(workers) and they start working
          bufferSize = 2;
          if(bufferSize == 2){
              for(int i = 0; i<2; i++){
                  jobs[i].jobMutex.unlock();
              }
          }
           break;
     }

  }

I started using std::thread a few days ago and I'm not sure why but Visual Studio gives me an error saying abort() has been called. I believe there's something missing however due to my ignorance I can't figure out what.

I would expect this piece of code to actually

  1. Initialize the two threads and then lock them

  2. Inside the main function unlock the two threads, the two threads will do their job(in this case nothing) and then they will become locked again.

But it gives me an error instead. What am I doing wrong?

Thank you in advance!

like image 953
ksm001 Avatar asked Apr 12 '13 16:04

ksm001


People also ask

What is the purpose of worker threads?

Worker thread is a continuous parallel thread that runs and accepts messages until the time it is explicitly closed or terminated. Messages to a worker thread can be sent from the parent thread or its child worker threads. Through out this document, parent thread is referred as thread where a worker thread is spawned.

How do you create a worker thread in C++?

The interface is shown below: class WorkerThread { public: /// Constructor WorkerThread(const char* threadName); /// Destructor ~WorkerThread(); /// Called once to create the worker thread /// @return True if thread is created.

How do I create a worker thread in node js?

The workerData is used for fetching the data from the thread and parentPort is used for manipulating the thread. The postMessage() method is used for posting the given message in the console by taking the filename as fetched by workerData. Here, the function runService() return a Promise and runs the worker thread.

What is main thread in C?

When a C# program starts up, one thread begins running immediately. This is usually called the main thread of our program. Properties: It is the thread under which other “child” threads will be created.


1 Answers

For this purpose you can use boost's threadpool class. It's efficient and well tested. opensource library instead of you writing newly and stabilizing it.

http://threadpool.sourceforge.net/

main()
{
    pool tp(2);   //number of worker threads-currently its 2.

    // Add some tasks to the pool.
    tp.schedule(&first_task);
    tp.schedule(&second_task);
}

void first_task()
{
    ...
}

void second_task()
{
    ...
}

Note:

Suggestion for your example: You don't need to have individual mutex object for each thread. Single mutex object lock itself will does the synchronization between all the threads. You are locking mutex of one thread in executejob function and without unlocking another thread is calling lock with different mutex object leading to deadlock or undefined behaviour.

Also since you are calling mutex.lock() inside whileloop without unlocking , same thread is trying to lock itself with same mutex object infinately leading to undefined behaviour.

If you donot need to execute threads parallel you can have one global mutex object can be used inside executejob function to lock and unlock.

mutex m;

void executeJob(int worker)
{
    m.lock();

    //do some job

    m.unlock();
}

If you want to execute job parallel use boost threadpool as I suggested earlier.

like image 75
shivakumar Avatar answered Sep 21 '22 02:09

shivakumar