mercredi 3 février 2016

Is it safe/efficient to cancel a c++ thread by writing to an outside variable?

I have a search problem, which I want to parallelize. If one thread has found a solution, I want all other threads to stop. Otherwise, if all threads exit regularly, I know, that there is no solution.

The following code (that demonstrates my cancelling strategy) seems to work, but I'm not sure, if it is safe and the most efficient variant:

#include <iostream>
#include <thread>
#include <cstdint>
#include <chrono>

using namespace std;

struct action {
  uint64_t* ii;

  action(uint64_t *ii) : ii(ii) {};

  void operator()() {
    uint64_t k = 0;
    for(; k < *ii; ++k) {
      //do something useful
    }
    cout << "counted to " << k << " in 2 seconds" << endl;
  }
  void cancel() {
    *ii = 0;
  }
};


int main(int argc, char** argv) {
  uint64_t ii = 1000000000;
  action a{&ii};
  thread t(a);
  cout << "start sleeping" << endl;
  this_thread::sleep_for(chrono::milliseconds(2000));
  cout << "finished sleeping" << endl;
  a.cancel();
  cout << "cancelled" << endl;
  t.join();
  cout << "joined" << endl;
}

Can I be sure, that the value, to which ii points, always gets properly reloaded? Is there a more efficient variant, that doesn't require the dereferenciation at every step? I tried to make the upper bound of the loop a member variable, but since the constructor of thread copies the instance of action, I wouldn't have access to that member later.

Also: If my code is exception safe and does not do I/O (and I am sure, that my platform is Linux), is there a reason not to use pthread_cancel on the native thread?

Aucun commentaire:

Enregistrer un commentaire