প্রকৃতপক্ষে যে উদাহরণটি আপনি সবে দিয়েছেন তার মধ্যে পার্থক্যগুলি দেখায় যদি আপনি একটি দীর্ঘ দীর্ঘ ক্রিয়া ব্যবহার করেন, যেমন
//! sleeps for one second and returns 1
auto sleep = [](){
std::this_thread::sleep_for(std::chrono::seconds(1));
return 1;
};
প্যাকেজড টাস্ক
একটি packaged_task
এটি নিজের থেকে শুরু হবে না, আপনাকে এটি শুরু করতে হবে:
std::packaged_task<int()> task(sleep);
auto f = task.get_future();
task(); // invoke the function
// You have to wait until task returns. Since task calls sleep
// you will have to wait at least 1 second.
std::cout << "You can see this after 1 second\n";
// However, f.get() will be available, since task has already finished.
std::cout << f.get() << std::endl;
std::async
অন্যদিকে, std::async
সঙ্গে launch::async
একটি ভিন্ন থ্রেড কাজের চালানোর চেষ্টা করা হবে:
auto f = std::async(std::launch::async, sleep);
std::cout << "You can see this immediately!\n";
// However, the value of the future will be available after sleep has finished
// so f.get() can block up to 1 second.
std::cout << f.get() << "This will be shown after a second!\n";
অপূর্ণতা
তবে আপনি async
সমস্ত কিছুর জন্য ব্যবহার করার চেষ্টা করার আগে মনে রাখবেন যে প্রত্যাশিত ভবিষ্যতের একটি বিশেষ ভাগাভাগি রাষ্ট্র রয়েছে যা দাবি করে যে future::~future
:
std::async(do_work1); // ~future blocks
std::async(do_work2); // ~future blocks
/* output: (assuming that do_work* log their progress)
do_work1() started;
do_work1() stopped;
do_work2() started;
do_work2() stopped;
*/
সুতরাং আপনি যদি সত্যিকারের অ্যাসিঙ্ক্রোনাস চান তবে আপনাকে ফেরত রাখা উচিত future
, বা যদি পরিস্থিতি পরিবর্তন হয় তবে আপনি যদি ফলাফলটির জন্য যত্ন নেন না:
{
auto pizza = std::async(get_pizza);
/* ... */
if(need_to_go)
return; // ~future will block
else
eat(pizza.get());
}
এই বিষয়ে আরও তথ্যের জন্য, ঔষধি Sutter এর নিবন্ধ দেখুন async
এবং~future
, যা সমস্যা বর্ণনা করে, এবং স্কট মেয়ার এর std::futures
থেকে std::async
বিশেষ হয় না , যা অর্ন্তদৃষ্টি বর্ণনা করা হয়েছে। এছাড়াও নোট করুন যে এই আচরণটি C ++ 14 এবং তার চেয়ে বেশি ক্ষেত্রে নির্দিষ্ট করা হয়েছিল , তবে সাধারণভাবে C ++ 11 এও প্রয়োগ করা হয়েছে implemented
আরও পার্থক্য
ব্যবহার করে std::async
আপনি আপনার নির্দিষ্ট কাজটি আর কোনও নির্দিষ্ট থ্রেডে চালাতে পারবেন না, যেখানে std::packaged_task
অন্যান্য থ্রেডে স্থানান্তরিত করা যেতে পারে।
std::packaged_task<int(int,int)> task(...);
auto f = task.get_future();
std::thread myThread(std::move(task),2,3);
std::cout << f.get() << "\n";
এছাড়াও, packaged_task
আপনাকে কল করার আগে একটি অনুরোধ করা দরকার f.get()
, অন্যথায় আপনার প্রোগ্রাম হিমশীতল হবে কারণ ভবিষ্যতে কখনই প্রস্তুত হবে না:
std::packaged_task<int(int,int)> task(...);
auto f = task.get_future();
std::cout << f.get() << "\n"; // oops!
task(2,3);
টি এল; ডিআর
ব্যবহারের std::async
আপনি কিছু কিছু কাজ এবং সত্যিই পরোয়া করি না যখন তারা কাজ করছি, এবং চান তাহলে std::packaged_task
আপনি তাদের অন্যান্য থ্রেড থেকে সরানো বা তাদের পরে ফোন করার জন্য জিনিষ আপ মোড়ানো চান। বা, খ্রিস্টানকে উদ্ধৃত করতে :
শেষে এ std::packaged_task
বাস্তবায়নের জন্য কেবলমাত্র একটি নিম্ন স্তরের বৈশিষ্ট্য std::async
(যার কারণে এটি std::async
অন্যান্য নিম্ন স্তরের স্টাফগুলির সাথে একসাথে ব্যবহৃত হলে এর চেয়ে আরও বেশি কিছু করতে পারে , যেমন std::thread
)। সহজভাবে কথিত a std::packaged_task
হ'ল একটি std::function
লিঙ্কযুক্ত std::future
এবং std::async
মোড়কে এবং একটিকে std::packaged_task
(সম্ভবত অন্য কোনও থ্রেডে) কল করে।