Asynchroniczne przerwanie wątków

Asynchroniczne przerwanie wątków
pingwindyktator
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 2 miesiące
  • 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.


do not code, write prose
edytowany 1x, ostatnio: pingwindyktator
_13th_Dragon
Przecież po pierwszym kroku pętli masz bezwarunkowego return'a WTF?
pingwindyktator
brakuje wąsów, już poprawiam
satirev
Porady na IRCu nie wystarczają? Nie ładnie...
pingwindyktator
Ściemniacie, to jest łatwe i da się to fajnie zrobić ;D
_13th_Dragon
A propos nazewnictwa, właśnie ze sprawdzaniem is_wrong masz asynchroniczne przerwanie, ponieważ każdy kończy działanie we własnym tempie. Natomiast chcesz centralizowanego zabijania wątków - czyli rozwiązanie synchroniczne.
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 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/


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 2x, ostatnio: _13th_Dragon
pingwindyktator
Przeczytałeś mój post do końca?
pingwindyktator
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 2 miesiące
  • 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.


do not code, write prose
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 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;
  }

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
pingwindyktator
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 2 miesiące
  • 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.


do not code, write prose
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 dni
0

Moment ale exit - kończy program.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
pingwindyktator
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 2 miesiące
  • 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.


do not code, write prose
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 dni
0

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


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
Wibowit
  • Rejestracja:około 20 lat
  • Ostatnio:9 minut
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?


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
pingwindyktator
Chyba jednak zdecyduje się na takie rozwiązanie rzeczywiście.
pingwindyktator
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 2 miesiące
  • 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);
}

do not code, write prose
edytowany 1x, ostatnio: pingwindyktator
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.