2012-10-31 24 views
11

這是前一個問題(here)的後續內容,但我正在研究一個多線程應用程序,我想將一個Boost packaged_task發佈到線程io_service。我卡住了使用C++ 03編譯器(所以std :: move不在),並且packaged_task不可複製。我試過把它包裝在一個shared_ptr中,然後傳遞它,還有很多其他的東西。這是我目前的嘗試和隨後的編譯器錯誤。任何想法如何讓這個工作?如何在C++ 03中將提升packaged_task發佈到io_service?

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(); 
} 

這導致:

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>]’ 

使用boost ::移動(任務)獲得了兩個錯誤:

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

你使用哪種升壓版本? – Rost

+1

在1.50 boost :: move(task)中應該可以工作。 –

+0

@Rost,@IgorR。,我用的是1.49,現在我用的是1.51,使用boost :: move(task)時仍然出現以下錯誤:'../boost_1_51_0/boost/asio/handler_invoke_hook.hpp:64: 3:錯誤:無法匹配'(boost :: detail :: thread_move_t >)()' '任何想法? –

回答

14

boost::packaged_task支持boost::move因爲升壓版本1.50,請參閱相應ticket

但問題是io_service::post完成處理程序參數必須是CopyConstructible,如Asio handler requirements中所述。因此boost::packaged_task不能直接發佈或移動。 (感謝Igor R.這個問題)。

有使用指針的解決方法,例如,你可以換用boost::packaged_taskboost::shared_ptr其綁定到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

你的解決方法是將operator()綁定到共享指針上。非常感謝你對我的幫助! –

+0

我很想知道這個展會是如何使用VC++ 10的。雖然共享打包任務似乎在posix(mac clang和linux gcc)上工作得很好,但我在Windows上遇到了很奇怪的錯誤 - >'成員函數已經定義或聲明' –

+0

@BenJ我剛在VC2010上使用Boost 1.53編譯此代碼,它編譯並工作正常(future.hpp中的C4913警告除外,但這是已知的Boost問題)。 – Rost

相關問題