2012-10-31 13 views
11

To jest kontynuacja poprzedniego pytania (here), ale pracuję nad aplikacją wielowątkową i chcę wysłać Boost packaged_task do wątku io_service. Utknąłem przy użyciu kompilatora C++ 03 (więc std :: move jest out), a packaged_task nie jest kopiowalny. Próbowałem owijać go w shared_ptr i przekazując go, i wiele innych rzeczy. Oto moja obecna próba i kolejne błędy kompilatora. Masz pomysł, jak to osiągnąć?Jak przesłać boost packaged_task do io_service w C++ 03?

boost::asio::io_service io_service; 
boost::thread_group threads; 
boost::asio::io_service::work work(io_service); 
for (int i = 0; i < maxNumThreads; ++i) 
{ 
    threads.create_thread(boost::bind(&boost::asio::io_service::run, 
     &io_service)); 
} 
std::vector<boost::shared_future<bool> > pending_data; // vector of futures 

bool process_data(int,int){...} 
... 

for(int theTime = 0; theTime != totalScenarioTime; ++theTime) 
{ 
    for(int i = 0; i < numSmallTasks; ++i) 
    { 
     boost::packaged_task<bool> task(boost::bind(&process_data,i,theTime)); 
     boost::shared_future<bool> fut(task.get_future()); 
     pending_data.push_back(fut); // C++11 possible: (std::move(fut) when fut is a unique_future); 
     io_service.post(task); // C++11 possible: (std::move(task));  
    } 
    // After loop - wait until all futures are evaluated 
    boost::wait_for_all(pending_data.begin(), pending_data.end()); 
    pending_data.clear(); 
} 

Skutkuje:

In file included from ../boostlibs/boost/asio/io_service.hpp:767:0, 
      from ../boostlibs/boost/asio/basic_io_object.hpp:19, 
      from ../boostlibs/boost/asio/basic_socket.hpp:19, 
      from ../boostlibs/boost/asio/basic_datagram_socket.hpp:20, 
      from ../boostlibs/boost/asio.hpp:20, 
      from ../main.cpp:13: 
../boostlibs/boost/asio/impl/io_service.hpp: In member function ‘void boost::asio::io_service::post(const CompletionHandler&) [with CompletionHandler = boost::packaged_task<bool>]’: 
../main.cpp:256:23: instantiated from here 
../boostlibs/boost/asio/impl/io_service.hpp:95:67: error: no matching function for call to ‘boost::packaged_task<bool>::packaged_task(const boost::packaged_task<bool>&)’ 
../boostlibs/boost/asio/impl/io_service.hpp:95:67: note: candidates are: 
../boostlibs/boost/thread/future.hpp:1372:9: note: boost::packaged_task<R>::packaged_task(boost::detail::thread_move_t<boost::packaged_task<R> >) [with R = bool] 
../boostlibs/boost/thread/future.hpp:1372:9: note: no known conversion for argument 1 from ‘const boost::packaged_task<bool>’ to ‘boost::detail::thread_move_t<boost::packaged_task<bool> >’ 
../boostlibs/boost/thread/future.hpp:1318:9: note: boost::packaged_task<R>::packaged_task() [with R = bool] 
../boostlibs/boost/thread/future.hpp:1318:9: note: candidate expects 0 arguments, 1 provided 
../boostlibs/boost/thread/future.hpp:1314:9: note: boost::packaged_task<R>::packaged_task(boost::packaged_task<R>&) [with R = bool, boost::packaged_task<R> = boost::packaged_task<bool>] 
../boostlibs/boost/thread/future.hpp:1314:9: note: no known conversion for argument 1 from ‘const boost::packaged_task<bool>’ to ‘boost::packaged_task<bool>&’ 
../boostlibs/boost/asio/detail/handler_type_requirements.hpp:95:26: error: initializing argument 1 of ‘T& boost::asio::detail::lvref(T) [with T = boost::packaged_task<bool>]’ 
../boostlibs/boost/asio/impl/io_service.hpp:95:67: error: no matching function for call to ‘boost::packaged_task<bool>::packaged_task(const boost::packaged_task<bool>&)’ 
../boostlibs/boost/asio/impl/io_service.hpp:95:67: note: candidates are: 
../boostlibs/boost/thread/future.hpp:1372:9: note: boost::packaged_task<R>::packaged_task(boost::detail::thread_move_t<boost::packaged_task<R> >) [with R = bool] 
../boostlibs/boost/thread/future.hpp:1372:9: note: no known conversion for argument 1 from ‘const boost::packaged_task<bool>’ to ‘boost::detail::thread_move_t<boost::packaged_task<bool> >’ 
../boostlibs/boost/thread/future.hpp:1318:9: note: boost::packaged_task<R>::packaged_task() [with R = bool] 
../boostlibs/boost/thread/future.hpp:1318:9: note: candidate expects 0 arguments, 1 provided 
../boostlibs/boost/thread/future.hpp:1314:9: note: boost::packaged_task<R>::packaged_task(boost::packaged_task<R>&) [with R = bool, boost::packaged_task<R> = boost::packaged_task<bool>] 
../boostlibs/boost/thread/future.hpp:1314:9: note: no known conversion for argument 1 from ‘const boost::packaged_task<bool>’ to ‘boost::packaged_task<bool>&’ 
../boostlibs/boost/asio/detail/handler_type_requirements.hpp:96:32: error: initializing argument 1 of ‘const T& boost::asio::detail::clvref(T) [with T = boost::packaged_task<bool>]’ 
../boostlibs/boost/asio/impl/io_service.hpp:97:3: error: no matching function for call to ‘boost::packaged_task<bool>::packaged_task(const boost::packaged_task<bool>&)’ 
../boostlibs/boost/asio/impl/io_service.hpp:97:3: note: candidates are: 
../boostlibs/boost/thread/future.hpp:1372:9: note: boost::packaged_task<R>::packaged_task(boost::detail::thread_move_t<boost::packaged_task<R> >) [with R = bool] 
../boostlibs/boost/thread/future.hpp:1372:9: note: no known conversion for argument 1 from ‘const boost::packaged_task<bool>’ to ‘boost::detail::thread_move_t<boost::packaged_task<bool> >’ 
../boostlibs/boost/thread/future.hpp:1318:9: note: boost::packaged_task<R>::packaged_task() [with R = bool] 
../boostlibs/boost/thread/future.hpp:1318:9: note: candidate expects 0 arguments, 1 provided 
../boostlibs/boost/thread/future.hpp:1314:9: note: boost::packaged_task<R>::packaged_task(boost::packaged_task<R>&) [with R = bool, boost::packaged_task<R> = boost::packaged_task<bool>] 
../boostlibs/boost/thread/future.hpp:1314:9: note: no known conversion for argument 1 from ‘const boost::packaged_task<bool>’ to ‘boost::packaged_task<bool>&’ 
../boostlibs/boost/asio/detail/impl/task_io_service.hpp:54:6: error: initializing argument 1 of ‘void boost::asio::detail::task_io_service::post(Handler) [with Handler = boost::packaged_task<bool>]’ 

Korzystanie boost :: ruch (zadanie) prowadzi do dwóch błędów:

error: no match for call to ‘(boost::detail::thread_move_t<boost::packaged_task<bool> >)()’ 
error: no match for call to ‘(boost::detail::thread_move_t<boost::packaged_task<bool> >)()’ 
+0

Która wersja doładowania używacie? – Rost

+1

W 1,50 boost :: move (zadanie) powinno działać. –

+0

@Rost, @IgorR., Używałem 1.49, teraz używam 1.51 i nadal otrzymuję następujący błąd podczas korzystania z boost :: move (zadanie): '../boost_1_51_0/boost/asio/handler_invoke_hook.hpp:64: 3: błąd: brak dopasowania dla wywołania "(boost :: detail :: thread_move_t >)() ' ' Jakieś pomysły? –

Odpowiedz

14

boost::packaged_task obsługującego boost::move od Boost, wersja 1.50, patrz odpowiedni ticket .

Ale problem polega na tym, że parametr zakończenia obsługi io_service::post musi być CopyConstructible, jak podano w Asio handler requirements. W związku z tym boost::packaged_task nie można opublikować bezpośrednio ani przesuwając. (Podziękowania dla Igor R. za ten problem).

Istnieje obejście za pomocą wskaźników, np. można owinąć boost::packaged_task z boost::shared_ptr i powiązać go z operator():

typedef boost::packaged_task<bool> task_t; 
boost::shared_ptr<task_t> task = boost::make_shared<task_t>(
    boost::bind(&process_data, i, theTime)); 

io_service.post(boost::bind(&task_t::operator(), task)); 
+0

Twoje obejście bindującego operatora() do udostępnionego wskaźnika zadziałało. Twoja pomoc z tym! –

+0

Byłbym bardzo zainteresowany, aby wiedzieć, jak te targi dla osób korzystających z VC++ 10. Podczas gdy wspólne zadania pakowane wydaje się działać dobrze na posix (mac clang i Linux gcc), dostaję bardzo dziwne błędy w systemie Windows -> 'funkcja członka już zdefiniowana lub zadeklarowana' –

+0

@BenJ Właśnie skompilowałem ten kod na VC2010 używając Boost 1.53 i kompiluje i działa OK (z wyjątkiem ostrzeżenia C4913 w future.hpp, ale jest to znany problem Boost). opublikuj swój aktualny kod? – Rost

Powiązane problemy