Asynchroniczne przerwanie wątków

Asynchroniczne przerwanie wątków
pingwindyktator
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Kraków
  • Postów: 1055
0
Kopiuj
#include <iostream>
#include <atomic>
#include <thread>
#include <list>

using namespace std;

atomic<bool> is_wrong(false);

void test () {
  for (size_t i = 0; i < 100; ++i) {
    if (rand() % 1000 == 0) { // uproszczona sytuacja
      is_wrong = true; // o TU
      return;
    }
  }
}

int main () {
  size_t number_of_threads = 10;
  list <thread> threads;

  for (size_t i = 0; i < number_of_threads; ++i)
    threads.emplace_back(test);

  for (thread &t : threads)
    t.join();

  cout << is_wrong;

  return 0;
}

Dzień dobry. Chcę, żeby wszystkie "wątki dzieci" zostały przerwane w momencie ustawienia is_wrong na true w którymś z nich. Jasne - mógłbym zrobić

Kopiuj
void test () {
  for (size_t i = 0; i < 100 && !is_wrong; ++i) {
    if (rand() % 1000 == 0) { // uproszczona sytuacja
      is_wrong = true; // o TU
      return;
    }
  }
}

ale chodzi o rozwiązanie asynchroniczne, tj bez ciągłego sprawdzania stanu is_wrong.

_13th_Dragon
  • Rejestracja: dni
  • Ostatnio: dni
1
Kopiuj
... for(size_t i=0;(!is_wrong)&&(i<100);++i) { ...

Ciągłe sprawdzanie is_wrong jest najlepszym rozwiązaniem inaczej musisz mieć listę wątków i robić na nich wszystkich operacje cancel() która jest naprawdę czasochłonna.
Może ma sens zastanowić się nad zamianą atomic<bool> na http://www.cplusplus.com/reference/mutex/call_once/

pingwindyktator
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Kraków
  • Postów: 1055
0

@_13th_Dragon nie potrafie sobie wyobrazić rozwiązania z call_once. atomic jest chyba bardzo okej w tym miejscu.

_13th_Dragon
  • Rejestracja: dni
  • Ostatnio: dni
0

Chyba jednak z call_once wyjdzie bardziej skomplikowane niż np takie coś:

Kopiuj
void test() 
  {
   for(size_t i=0;i<100;++i) if(is_wrong=is_wrong|(rand()%1000==0)) return;
  }
pingwindyktator
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Kraków
  • Postów: 1055
0

Tak się zastanawiam - użycie exit byłoby bardzo brzydkie tutaj, nie? To w sumie proste i działające rozwiązanie by było.

_13th_Dragon
  • Rejestracja: dni
  • Ostatnio: dni
0

Moment ale exit - kończy program.

pingwindyktator
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Kraków
  • Postów: 1055
0

No tak. Ale czasem można przerzucić funkcjonalność wątku głównego do osobnej funkcji, tam na końcu dać exit i te funkcje wywoływać. Trochę naokoło i nie do końca o to chodzi w ogólnym przypadku, ale czasem będzie dobrze.

_13th_Dragon
  • Rejestracja: dni
  • Ostatnio: dni
0

Jeszcze raz powtarzam - exit() - kończy działanie całego programu, nie pojedynczego wątku.

Wibowit
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: XML Hills
1

ale chodzi o rozwiązanie asynchroniczne, tj bez ciągłego sprawdzania stanu is_wrong.

Asynchroniczna obsługa flagi służącej do synchronizacji? Nie ma tu sprzeczności?

Rozwiązanie z atomic boolem jest naturalne i logiczne, po co kombinować dalej?

pingwindyktator
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Kraków
  • Postów: 1055
0

Nie musisz mi tego mówić. Ale jaki był główny problem? Zabić wszystkie wątki oprócz wątku głównego. Czasami da się to obejść tak, że tworzysz funkcje

Kopiuj
void exit_wrapper() {
  // tutaj wszystko z maina co miało być po zakończeniu pracy wątków dzieci
  exit(0);
}
  • Rejestracja: dni
  • Ostatnio: dni
0

Pewnie musisz użyć.. ten, no... event. :)

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.