1

My int main uses a while (1) loop to run my code. If I want to start continuous threads before I enter my while loop, would it look like this?

int main ()
{
     boost::thread_group threads;
     threads.create_thread (check_database);
     while (1)
     {
          // main program
     }
}

void check_database_and_plc ()
{
     while (1)
     {
          // check database, and if it needs to take action, do so;
          // this function / thread will never stop;
          // it will continuously check a single value from mysql and take
          // action based on that number (if 1, write to PLC, if 2, change
          // screens, etc);
          // also check plc for any errors, if there are any, tell int main
     }
}

Therefore I have two while loops running at the same time. Is there a better way to do this? Thank you for your time.

Barry
  • 286,269
  • 29
  • 621
  • 977
xinthose
  • 3,213
  • 3
  • 40
  • 59
  • 2
    Looks fine. You might want to add some interrupt/stop condition, though. And don't forget to correctly protect the database, so that access (read/write) to it is thread-safe. Edit: on second thought, if the change in the database is caused by some specific action in `main`, you can use `signal()` and `wait()` methods to prevent the `check_database()` from using CPU if not needed. – Yellows Jan 23 '15 at 03:19
  • how would I do that exactly? – xinthose Jan 23 '15 at 03:31
  • do they have a happen-before relationship? – qqibrow Jan 23 '15 at 03:33
  • 1
    @sinthose: Relevant links: http://stackoverflow.com/questions/25082563/using-a-boost-thread-signal-and-wait-for-termination ; http://stackoverflow.com/questions/16907072/how-do-i-use-a-boost-condition-variable-to-wait-for-a-thread-to-complete-process – Yellows Jan 23 '15 at 03:38
  • I am not quite sure what your requirements are. – Yakk - Adam Nevraumont Jan 23 '15 at 03:39
  • no, but if I wanted to return a value from check_database to int main if it sees something, how would I do that? – xinthose Jan 23 '15 at 03:40
  • @xinthose What do you mean by "return a value from check_database to int main if it sees something"? Complete code and goals would be helpful. – Yellows Jan 23 '15 at 03:42
  • sorry; so if check_database_and_plc sees an error in my plc, it should tell int main immediately somehow. I could just write a bit to mysql and read it from int main – xinthose Jan 23 '15 at 03:46
  • 1
    Look at my answer. Feel free to further ask if it does not match your requirements. – Yellows Jan 23 '15 at 03:57
  • 1
    Why would you mix DB and PLC checks? I'd move that into two threads, so you can also configure the interval between the checks more freely. – Ulrich Eckhardt Jan 23 '15 at 07:04

1 Answers1

2

From you comment, I would (as a first try!) understand you need something like this:

bool plc_error = false;
boost::condition_variable cv;
boost::mutex mutex;
int main ()
{
     boost::thread_group threads;
     threads.create_thread (check_database);
     while (1)
     {

          boost::mutex::scoped_lock lock(mutex);
          while(!plc_error)
              cv.wait(lock);
          // deal with the error
          plc_error = false;
     }
}

void check_database_and_plc ()
{
     while (1)
     {
          // sleep a bit to ensure main will not miss notify_one()
          // check database and plc
          if (error){
              plc_error = true;
              cv.notify_one();
          }
     }
}

I did not take into account terminating and joining the thread into main, but the links I gave in the comments should help you.

Yellows
  • 693
  • 4
  • 14
  • 2
    You' re welcome. This is common for multithreaded programming - I would suggest reading a bit of theory on the subject (keywords: threads, synchronization, mutexs, semaphores, condition variables, or some Operating Systems course/textbook), it will give you the best tools to solve optimally your problem. It is very important, since concurrent programming is much less intuitive than serial (regular?) coding. – Yellows Jan 23 '15 at 04:08
  • so if at any point in int main's while (1) loop, plc_error is true, it will immediately go to the second while(!plc_error) loop, deal with the error, set it back to false, then continue on with the while (1) loop? – xinthose Jan 23 '15 at 16:30
  • 1
    No. The `check()` thread will send a "notification" to any other thread waiting for a notification, and then go on with execution. Since here we have only two threads, it will "wake up" the `main()` thread, which is sleeping until it receives a message. – Yellows Jan 24 '15 at 16:39