Wszystkie wskazówki, które zostały zgłoszone powyżej, są poprawne dla programów sekwencyjnych, tzn. Programów bez wątków. Używanie wątków zmienia się. Po pierwsze, domyślnie parametrami do std :: thread są parametry funkcji i funkcji. Prawdopodobnie były studia Książka "C++ współbieżność w akcji", a autor przedstawia interesujący przykład:
void do_some_work();
thread my_thread(do_some_work); //thread receives the function address
Załóżmy tę funkcję:
void do_other_job (int k); W organizmie kodu, należy zrobić:
k=3;
thread my_thread2(do_other_job, k);
w celu tarło innego wątku.
Tak więc, za pomocą gwintów kompilator interpretuje f (w std :: gwintu my_thread (F);) domyślnie jako funkcję zamiast klasy. Aby zmienić, musisz zainicjować operator(), aby ostrzec kompilatora, który pracuje z klasą. Alternatywą kod może być:
class background_task{
public:
background_task(){
do_sth();
do_sth_else();
}
void operator()(){}
};
background_task f;
thread mythread10(f);
Ostatecznie, to nie jest poprawna, za pomocą wątków, karmienie operatora, więc ten kod nie działa:
void operator()(int x){
do_sth();
cout<<"x = "<<x<<endl;
}
Zdarza się, ponieważ cały kod wewnątrz nawiasy są tylko do odczytu i nie można ich zmienić w czasie wykonywania. Jeśli chcesz wstawić zmienną do konstruktora, musisz ją włączyć do inicjowania wątku. A więc:
class backg{
public:
backg(int i){
do_sth(i);
}
void operator()(){}
};
int main(){
thread mythread{ backg(12) }; //using c++11
return 0;
}
Będzie działał bez błędów i wykona funkcję do_sth (12) w zarodku wątku.
Mam nadzieję, że pomogłem.
fajne, bardziej przejrzyste teraz. –
Czy są jakieś niejawne wywołania operatora()() z wyjątkiem tego jawnego zadania wywołania()? –
@ forester2012, nie musisz zawsze wywoływać go jawnie, chociaż możesz użyć znacznie bardziej niezręcznej składni 'task.operator()()'. Istnieje wiele standardowych algorytmów, które będą wywoływać ten operator wewnętrznie. –