Po this excellent tutorial dla futures, obietnic i pakietach zadań dotarłem do punktu, w którym chciałem przygotować własne zadanieJak utworzyć parametr packaged_task z parametrami?
#include <iostream>
#include <future>
using namespace std;
int ackermann(int m, int n) { // might take a while
if(m==0) return n+1;
if(n==0) return ackermann(m-1,1);
return ackermann(m-1, ackermann(m, n-1));
}
int main() {
packaged_task<int(int,int)> task1 { &ackermann, 3, 11 }; // <- error
auto f1 = task1.get_future();
thread th1 { move(task1) }; // call
cout << " ack(3,11):" << f1.get() << endl;
th1.join();
}
O ile mogę rozszyfrować gcc-4.7.0 komunikat o błędzie inaczej oczekuje argumentów? Ale jak? Staram się skrócić komunikat o błędzie:
error: no matching function for call to
'std::packaged_task<int(int, int)>::packaged_task(<brace-enclosed initializer list>)'
note: candidates are:
std::packaged_task<_Res(_ArgTypes ...)>::---<_Res(_ArgTypes ...)>&&) ---
note: candidate expects 1 argument, 3 provided
...
note: cannot convert 'ackermann'
(type 'int (*)(int, int)') to type 'std::allocator_arg_t'
jest mój wariant jaki sposób zapewnić parametry ackermann
złym? Czy jest to zły parametr szablonu? Nie podaję parametrów 3,11
do tworzenia wątku, prawda?
Aktualizuj inne nieudane warianty:
packaged_task<int()> task1 ([]{return ackermann(3,11);});
thread th1 { move(task1) };
packaged_task<int()> task1 (bind(&ackermann,3,11));
thread th1 { move(task1) };
packaged_task<int(int,int)> task1 (&ackermann);
thread th1 { move(task1), 3,11 };
hmm ... czy to ja, czy jest to beta-gcc?
Patrząc na wymagania dla 'std :: bind', nie jest prawdą, że argumenty są wymagane do kopiowania. Paragraf jest zbyt długi, aby go tu wkleić, to jest 20.8.9.1.2 Powiązanie szablonu funkcji [func.bind.bind] paragraf 5. Rzeczywiste wymagania są takie, że przechowywane typy są ruchome i możliwe do skonstruowania na podstawie przekazanych argumentów. Chociaż pamiętam wadliwe wdrożenie wysyłki z GCC, które wymagało CopyConstructible. (Nie dotyczy to jednak problemu z OP). –
@ Luc: Masz rację, źle pamiętam. –
Kod działa, ale mam pytanie w linii 'std :: unique_lock l (td.m);' nie jest mutex w wątku już zablokowanym podczas sprawdzania zmiennej warunku? Chyba coś tam mi brakuje. Myślałem, że blokuje muteks w wątku, a następnie czeka, aż flaga stopu lub praca zostanie dodana do kolejki. Czy w takim przypadku główny wątek nie czekałby na blokadę wydanego? Czy to z powodu fałszywego przebudzenia, że to działa? –
bjackfly