2012-10-31 24 views
11

Đây là một sự theo dõi từ một câu hỏi trước (here), nhưng tôi đang làm việc trên một ứng dụng đa luồng và tôi muốn đăng một gói packaged_task Boost lên một luồng io_service. Tôi đang mắc kẹt bằng cách sử dụng một trình biên dịch C + + 03 (vì vậy std :: di chuyển là ra), và packaged_task không phải là copyable. Tôi đã thử gói nó trong một shared_ptr và đi qua đó, và rất nhiều thứ khác. Đây là nỗ lực hiện tại của tôi và các lỗi trình biên dịch tiếp theo. Bất kỳ ý tưởng làm thế nào để có được điều này để làm việc?Làm thế nào để bạn đăng một packaged_task tăng lên một io_service trong 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(); 
} 

Điều này dẫn đến:

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

Sử dụng boost :: kết quả di chuyển (nhiệm vụ) trong hai lỗi:

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

Bạn sử dụng phiên bản Boost nào? – Rost

+1

Trong 1.50 boost :: move (task) sẽ hoạt động. –

+0

@Rost, @IgorR., Tôi đã sử dụng 1,49, hiện đang sử dụng 1,51 và tôi vẫn nhận được lỗi sau khi sử dụng boost :: move (task): '../boost_1_51_0/boost/asio/handler_invoke_hook.hpp:64: 3: lỗi: không khớp cho cuộc gọi đến '(tăng :: chi tiết :: thread_move_t >)()' 'Bất kỳ ý tưởng nào? –

Trả lời

14

boost::packaged_task hỗ trợ boost::move từ Boost phiên bản 1.50, xem tương ứng ticket .

Nhưng vấn đề là thông số xử lý hoàn thành io_service::post phải là CopyConstructible như được ghi chú trong Asio handler requirements. Do đó, không thể đăng trực tiếp hoặc bằng cách di chuyển boost::packaged_task. (Cảm ơn Igor R. về vấn đề này).

Có cách giải quyết khác bằng cách sử dụng con trỏ, ví dụ: bạn có thể quấn boost::packaged_task với boost::shared_ptr và liên kết nó với 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

công việc của bạn về toán tử liên kết() với con trỏ chia sẻ đã làm việc. sự giúp đỡ của bạn với điều này! –

+0

Tôi sẽ rất quan tâm để biết làm thế nào hội chợ này cho người sử dụng VC + + 10. Trong khi chia sẻ đóng gói nhiệm vụ dường như làm việc tốt trên posix (mac clang và linux gcc), tôi nhận được rất lạ lỗi trên windows -> 'Chức năng thành viên đã được xác định hoặc khai báo' –

+0

@BenJ Tôi vừa biên soạn mã này trên VC2010 bằng cách sử dụng Boost 1.53 và nó biên dịch và hoạt động OK (ngoại trừ cảnh báo C4913 trong tương lai.hpp nhưng vấn đề này được biết là Boost). bạn xin vui lòng gửi mã thực tế của bạn? – Rost