0

I have a program doing 'assignments' that are scheduled by boost::threadpool. Each of those assignments take a lot of time (1 min - 5h per assignment). I wan't to monitor progress for each assignment, to understand how long will the process take.

There are a lot more assignments then there are threads, so only NUM_THREADS of progress outputs should be visible.

I have created a simple piece of code that does this, but there 2 problems:

  • I don't think it's elegant.
  • Don't know if incrementing prog like this is safe.

What would be the better ways of doing this?


#include <thread>
#include <iostream>
#include <atomic>
#include <vector>


volatile int prog[4]={0,0,0,0};
std::atomic<bool> prog_lock[4];

bool end(){
  bool ret=true;
  for(int i=0;i<4;i++)
    if(prog[i]!=100){
      ret=false;
      break;
    }

  return ret;

}
void Func(){

  int prog_ind=0;
  for(int i=0;i<4;i++){
    if(!prog_lock[i].exchange(true)){
      prog_ind=i;
      break;
    }
  }

  for(int i=0;i<100;i++){
    prog[prog_ind]++;
    std::this_thread::sleep_for(std::chrono::milliseconds(300));

  }
  prog_lock[prog_ind].store(false);

}


int main(){
  for(int i=0;i<4;i++)
    prog_lock[i].store(false);

  std::vector<std::thread> thr;
  for(int i=0;i<4;i++){
    thr.push_back(std::thread(Func));
  }

  while(!end()){
    std::cout << std::string(50,' ')  << "\r";
    for(int i=0;i<4;i++){

      std::cout << "Progress: " << prog[i] << "/100\t";
    }
    std::cout << "\r" << std::flush;
    std::this_thread::sleep_for(std::chrono::seconds(1));
  }
  for(int i=0;i<4;i++)
    thr[i].join();

}
UldisK
  • 1,619
  • 1
  • 17
  • 25
  • Since `prog` is not atomic, I would say that you may report bad values (in `main`) and test with bad values (in `end()`). – Jarod42 Jan 31 '14 at 13:52
  • As `prog` is `volatile`, the values may be outdated, but not by large value, and since read is once per second, it shouldn't be far off. – UldisK Jan 31 '14 at 14:15
  • I mean `prog[0]` may be partially written when the other thread reads it. – Jarod42 Jan 31 '14 at 14:21
  • Based on this thread: http://stackoverflow.com/questions/5002046/atomicity-in-c-myth-or-reality I understand that those int writes should be atomic, so no partial writes are possible – UldisK Jan 31 '14 at 15:27
  • According to your link, atomicity can be guaranteed on a **given** architecture, but not generally. So your code is not portable. Note: If atomicity is guaranteed on your platform, and if increment is not atomic, then you may read outdated value, which is not a problem *in your case*. – Jarod42 Jan 31 '14 at 15:48

0 Answers0