1

I have the following code as my main function:

int main(int argc,char** argv)
{
    CommandLineParser cmd(argc,argv,keys);
  if (cmd.has("help")) {
      cmd.about("");
      cmd.printMessage();
      return 0;
  }
  String alphaFile = cmd.get<String>("alpha");
  String betaFile = cmd.get<String>("beta");
  String gammaFile = cmd.get<String>("gamma");
  String deltaFile = cmd.get<String>("delta");
  int featureToUse = cmd.get<int>("feature");
  int classifier = cmd.get<int>("classifier");

  runOnSingleCamera(alphaFile, featureToUse, classifier);
  runOnSingleCamera(betaFile, featureToUse, classifier);
  runOnSingleCamera(gammaFile, featureToUse, classifier);
  runOnSingleCamera(deltaFile, featureToUse, classifier);

  return 0;
}

runOnSingleCamera is one of my other functions, and each call runs the same thing on different video files. The code needs to run simultaneously on all video files and access the same global array.

What would be the best way of doing this?

If the solution is multithreading, please advise as to what should be included in my cmake file, as I have experimented with this but could not get it to work.

TomRobson
  • 99
  • 1
  • 10

1 Answers1

2

How about this:

int main(int argc,char** argv)
{
    CommandLineParser cmd(argc,argv,keys);
  if (cmd.has("help")) {
      cmd.about("");
      cmd.printMessage();
      return 0;
  }
  String alphaFile = cmd.get<String>("alpha");
  String betaFile = cmd.get<String>("beta");
  String gammaFile = cmd.get<String>("gamma");
  String deltaFile = cmd.get<String>("delta");
  int featureToUse = cmd.get<int>("feature");
  int classifier = cmd.get<int>("classifier");

  std::thread t1(runOnSingleCamera, alphaFile, featureToUse, classifier);
  std::thread t2(runOnSingleCamera, betaFile, featureToUse, classifier);
  std::thread t3(runOnSingleCamera, gammaFile, featureToUse, classifier);
  std::thread t4(runOnSingleCamera, deltaFile, featureToUse, classifier);

  t1.join();
  t2.join();
  t3.join();
  t4.join();

  return 0;
}

Multithreading is though not a toy. If everything is independent here, then this is OK. If variables depend on each other in some way, you have to be careful.

If your array is read-only, then this is OK. If your array needs to be modified by all threads, then this is a destruction recipe. Again, really be careful with shared variables among threads. It's a very big topic. Read about race-conditions.

Be aware that with this everything is passed by value; i.e., everything is copied to your function (even if your function takes stuff by reference). You should use std::ref() to pass by reference. Read more about std::thread here.

Community
  • 1
  • 1
The Quantum Physicist
  • 24,987
  • 19
  • 103
  • 189
  • This is what I was referring to when I said I couldn't get multithreading to work, apologies for lack of clarity, I get the following error: – TomRobson Mar 24 '17 at 12:55
  • /usr/bin/ld: CMakeFiles/main.dir/main.cpp.o: undefined reference to symbol 'pthread_create@@GLIBC_2.2.5' //lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line collect2: error: ld returned 1 exit status CMakeFiles/main.dir/build.make:163: recipe for target 'main' failed make[2]: *** [main] Error 1 CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/main.dir/all' failed make[1]: *** [CMakeFiles/main.dir/all] Error 2 Makefile:83: recipe for target 'all' failed make: *** [all] Error 2 – TomRobson Mar 24 '17 at 12:55
  • @TomRobson You have to link to pthread. Link using the flag `-pthread`. You can use `target_link_libraries` in cmake to achieve this. For example `target_link_libraries(MyExec -pthread)`. Replace `MyExec` with your object in cmake. – The Quantum Physicist Mar 24 '17 at 12:56
  • Also my array does need to be modified by all threads, and is declared globally, does this mean I need to use locks and/or mutexes? – TomRobson Mar 24 '17 at 12:57
  • 1
    I'll also caution that if these functions are accessing the same global array and they are modifying it then you need to build in synchronization in the function. – NathanOliver Mar 24 '17 at 12:57
  • @TheQuantumPhysicist this now compiles, but when I try to run it I get the following error: `[xcb] Unknown request in queue while dequeuing [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called [xcb] Aborting, sorry about that. main: ../../src/xcb_io.c:179: dequeue_pending_request: Assertion `!xcb_xlib_unknown_req_in_deq' failed. Aborted (core dumped) ` – TomRobson Mar 24 '17 at 13:00
  • @TomRobson I mentioned that it's OK if the array is read only. It's also OK if every thread modifies different parts of the array. Otherwise, if all threads have to modify the same parts of the array, then I recommend that you either forget it, or start reading a book on multithreading. This is not a joke and will deliver wrong results. – The Quantum Physicist Mar 24 '17 at 13:00
  • @TomRobson Google this problem. The GUI library of Linux is having a problem with your multithreading. You have to spend some time to understand why this happens. I can't help you from here. – The Quantum Physicist Mar 24 '17 at 13:04