বুস্ট :: থ্রেড এবং বুস্ট :: মিটেক্সকে সি ++ 11 সমমানের সাথে প্রতিস্থাপন করা কি স্মার্ট?


153

অনুপ্রেরণা: কারণ কেন আমি এটি বিবেচনা করছি তা হ'ল আমার প্রতিভা প্রকল্পের পরিচালক মনে করেন যে উত্সাহ আরেকটি নির্ভরতা এবং এটি ভয়ঙ্কর কারণ "আপনি এটির উপর নির্ভরশীল" (আমি উত্সাহের গুণমানটি ব্যাখ্যা করার চেষ্টা করেছি, পরে কিছুক্ষণ পরে ছেড়ে দিয়েছি :( )। আমি এটি করতে চাইলে ছোট কারণ হ'ল আমি সি ++ ১১ টি বৈশিষ্ট্য শিখতে চাই, কারণ লোকেরা এতে কোড লিখতে শুরু করবে: সুতরাং:

  1. #include<thread> #include<mutex>সমতুল্যের মধ্যে বুস্ট করার জন্য কি 1: 1 ম্যাপিং রয়েছে ?
  2. আপনি কি C ++ 11
    স্টাফ দিয়ে বুস্ট স্টাফগুলি প্রতিস্থাপন করার জন্য একটি ভাল ধারণা বিবেচনা করবেন ? আমার ব্যবহার আদিম, কিন্তু যখন উদাহরণস্বরূপ কী প্রস্তাব দেয় তা কী প্রস্তাব দেয়? নাকি (নিন্দা) এর বিপরীতে?

PS আমি জিসিসি ব্যবহার করি তাই শিরোনাম আছে।


46
আইএমও গুগল কোডিং গাইডলাইনগুলি বিভিন্ন উপায়ে বোকা ... উদাহরণস্বরূপ। তারা সি ++ 11 থেকে
অটোকে

5
উদ্ধৃতি নির্দেশিকা: [অটো] পাঠ্যতা ব্যাহত করে [কারণ এটি সরিয়ে দেয়] চেক করা রিডানডেন্সি (যেমন টাইপের নাম) যা পাঠকদের জন্য সহায়ক হতে পারে।
অ্যান্ড্রু তোমাজস

31
এর জন্য (অটো এটি = ভি.বেগিন () ... :)
NoSenseEtAl

15
@ অ্যান্ড্রুটোমাজস-ফ্যাথমলিং: সত্যি? ব্যক্তিগতভাবে আমি ভাবি না যে আমি পুনরাবৃত্তির আসল প্রকারের বিষয়ে যত্ন নিয়েছি (বেশ কয়েকবার ভালই হতে পারে), কেবলমাত্র সমর্থিত ক্রিয়াকলাপ ... আমি যুক্তি দিয়ে বলব যে সিনট্যাক্টিকাল রিডানডেন্সি খুব কমই একটি ভাল চিন্তা (DRY) is
গ্রিজলি

16
বিটিডাব্লু গুগল তার বোবা নির্দেশিকাটি পরিবর্তন করেছে তাই শেষ পর্যন্ত তারা
অটোকে

উত্তর:


192

বুস্ট.থ্রেড এবং সি ++ 11 স্ট্যান্ডার্ড থ্রেড লাইব্রেরির মধ্যে বেশ কয়েকটি পার্থক্য রয়েছে:

  • বুস্ট থ্রেড বাতিলকরণকে সমর্থন করে, সি ++ 11 থ্রেড করে না
  • সি ++ 11 সমর্থন করে std::asyncতবে বুস্ট দেয় না
  • বুস্টের boost::shared_mutexএকাধিক-পাঠক / একক লেখক লকিংয়ের জন্য রয়েছে। অনুরূপ std::shared_timed_mutexশুধুমাত্র সি ++ 14 (যেহেতু পাওয়া যায় N3891 ,) যখন std::shared_mutexশুধুমাত্র সি ++ 17 (যেহেতু পাওয়া যায় N4508 )।
  • সি ++ ১১ টি টাইমআউটগুলি বুস্ট টাইমআউটগুলির চেয়ে পৃথক (যদিও এটি শীঘ্রই এখন বুস্ট পরিবর্তন করা উচিত h ক্রোনো গৃহীত হয়েছে)।
  • কিছু নাম আলাদা (যেমন boost::unique_futureবনাম std::future)
  • এর আর্গুমেন্ট-পাসিং শব্দার্থের তুলনায় --- বুস্ট ব্যবহারগুলি std::threadআলাদা , যার জন্য অনুলিপিযোগ্য আর্গুমেন্ট প্রয়োজন। কেবল চালিত-প্রকারের যেমন আর্গুমেন্ট হিসাবে পাস করার অনুমতি দেয় । ব্যবহারের কারণে , প্লেসমোল্ডারগুলির শব্দার্থক যেমন নেস্টেড বাইন্ড এক্সপ্রেশনগুলিতেও আলাদা হতে পারে।boost::threadboost::bindstd::threadstd::unique_ptrboost::bind_1
  • আপনি যদি স্পষ্টভাবে কল না করেন join()বা detach()তারপরে boost::threadডেস্ট্রাক্টর এবং অ্যাসাইনমেন্ট অপারেটর detach()থ্রেড অবজেক্টটি নষ্ট / নির্ধারিত হওয়ার জন্য কল করবে । একটি সি ++ 11 std::threadঅবজেক্টের সাথে, এর ফলে কলটি হবে std::terminate()এবং অ্যাপ্লিকেশনটি বাতিল করতে হবে।

কেবল স্থানান্তরিত পরামিতিগুলি সম্পর্কে পয়েন্টটি পরিষ্কার করতে, নিম্নলিখিতটি বৈধ সি ++ 11, এবং নতুন থ্রেড শুরু হওয়ার পরে intঅস্থায়ী std::unique_ptrথেকে প্যারামিটারের মালিকানা স্থানান্তর করে f1। তবে, আপনি যদি ব্যবহার করেন boost::threadতবে এটি কাজ করবে না, কারণ এটি boost::bindঅভ্যন্তরীণভাবে ব্যবহার করে, এবং std::unique_ptrঅনুলিপি করা যায় না। জিসিসির সাথে সরবরাহিত সি ++ 11 থ্রেড লাইব্রেরিতে একটি ত্রুটি রয়েছে যা এই কাজকে বাধা দেয়, কারণ এটি std::bindসেখানে প্রয়োগের ক্ষেত্রেও ব্যবহার করে।

void f1(std::unique_ptr<int>);
std::thread t1(f1,std::unique_ptr<int>(new int(42)));

আপনি যদি বুস্ট ব্যবহার করছেন তবে আপনার সংকলক এটি সমর্থন করলে আপনি সম্ভবত সি ++ 11 থ্রেডগুলিতে তুলনামূলকভাবে বেদাহীনভাবে পরিবর্তন করতে পারেন (যেমন লিনাক্সের জিসিসির সাম্প্রতিক সংস্করণগুলিতে -std=c++0xমোডে উপলব্ধ সি ++ 11 থ্রেড লাইব্রেরির বেশিরভাগ সম্পূর্ণ বাস্তবায়ন রয়েছে )।

যদি আপনার সংকলক সি ++ 11 থ্রেড সমর্থন করে না তবে আপনি জাস্ট :: থ্রেডের মতো কোনও তৃতীয় পক্ষের বাস্তবায়ন পেতে সক্ষম হতে পারেন তবে এটি এখনও নির্ভরতা।


1
পাঠক এবং লেখকদের জন্য পৃথক লক / আনলক পদ্ধতি রয়েছে ( lock/ unlockলেখকদের জন্য বনাম 'লক_শ্রেড / আনলক_শ্রেড্ড' পাঠকদের জন্য)। একাধিক পাঠক যতক্ষণ না কোনও লেখক এটি ব্যবহার না করে অবরুদ্ধ না করে লক_শায়ারড কল করতে পারেন।
ডেভ এস

2
shared_mutexডক্সে হয় boost.org/doc/libs/1_47_0/doc/html/thread/... । আপনি মিটেক্সকে ভাগ বা একচেটিয়া হিসাবে লক করেছেন এবং তারপরে সংশ্লিষ্ট আনলক ফাংশনটি ব্যবহার করুন। এটি করার জন্য আপনি RAII ধরণগুলিও ব্যবহার করতে পারেন ( shared_lockএকটি ভাগ করা পঠিত লক নেয় lock_guardএবং unique_lockএকটি বিশেষ লকটি নিয়ে যায়)। আমি কেবল স্থানান্তরিত প্রকারের বিষয়ে বিষয়টি পরিষ্কার করার চেষ্টা করেছি।
অ্যান্টনি উইলিয়ামস

3
আর একটি ছোটখাটো জিনিস যা আমাকে ছুঁড়ে ফেলেছে : উত্সাহিতভাবে, চলমান থ্রেডের ডেস্ট্রাক্টর এটি আলাদা করে দেয় ( boost.org/doc/libs/1_47_0/doc/html/thread/… ), যখন সি ++ তে চলমান থ্রেড কলগুলির ডেস্ট্রাক্টর সমাপ্ত হয় () (এফডিআইএস 30.3.1.3)
কুবিবি

3
সি ++ 11 এ try_scoped_lockকার্যকারিতা আচ্ছাদিত std::unique_lock। এমন একটি কনস্ট্রাক্টর রয়েছে যা একটি মিটেক্স গ্রহণ করে std::try_to_lockএবং তারপরে try_lock()মুটেক্সের পরিবর্তে কল করবে lock()। দেখুন stdthread.co.uk/doc/headers/mutex/unique_lock/…
অ্যান্টনি উইলিয়ামস

4
হ্যাঁ, বুস্ট.ট্রেড মূলত ভিসেন্টে বোটেটের কাজের কারণে আমি এটি লেখার পর থেকে সি ++ 11 মানের আরও বেশি ঘনিষ্ঠ হয়ে উঠছি।
অ্যান্টনি উইলিয়ামস

24

std::threadবেশ কয়েকটি পার্থক্যboost::thread সহ বেশিরভাগ পরে মডেল করা হয় :

  • বুস্টের অন-অনুলিপিযোগ্য, এক-হ্যান্ডেল-মানচিত্র-থেকে-এক-ওএস-থ্রেড, শব্দার্থবিজ্ঞান ধরে রাখা হয়েছে। তবে এই থ্রেডটি কারখানার ফাংশনগুলি থেকে থ্রেড ফেরত দেওয়ার এবং পাত্রে রাখার অনুমতি দেওয়ার জন্য অস্থাবর।
  • এই প্রস্তাবটি বাতিলকে যুক্ত করে boost::thread, যা একটি উল্লেখযোগ্য জটিলতা। এই পরিবর্তনটি কেবল থ্রেডেই নয় তবে বাকী সি ++ থ্রেডিং লাইব্রেরিরও একটি বড় প্রভাব ফেলে। এটি বিশ্বাস করা হয় যে সুবিধার কারণে এই বৃহত পরিবর্তনটি ন্যায়সঙ্গত।
    • থ্রেড ডেস্ট্রাক্টরকে এখন পিতামাতার থ্রেড বাতিল হয়ে যাওয়ার পরে ঘটনাক্রমে শিশুদের থ্রেডগুলি ফাঁস হওয়া এড়ানোর জন্য আলাদা করতে আগে কল করতে হবে।
    • একটি স্পষ্ট বিচ্ছিন্ন সদস্য এখন বাতিল না করে বিচ্ছিন্নকরণ সক্ষম করতে প্রয়োজন।
  • থ্রেড হ্যান্ডেল এবং থ্রেড পরিচয়ের ধারণাগুলি দুটি শ্রেণিতে বিভক্ত করা হয়েছে (তারা একই শ্রেণিতে হয় boost::thread)। এটি হ'ল থ্রেড আইটেমির সহজ হেরফের এবং স্টোরেজ সমর্থন করে।
  • কোনও থ্রেড আইডি তৈরির সক্ষমতা যা অন্য কোনও জয়েন্টেবল থ্রেডের সমান তুলনা করার গ্যারান্টিযুক্ত যুক্ত করা হয়নি (এটিতে boost::threadনেই)। এটি কোডের জন্য কার্যকর যা এটি জানতে চায় যে এটি পূর্ববর্তী কল হিসাবে একই থ্রেড দ্বারা কার্যকর করা হচ্ছে কিনা (পুনরাবৃত্তিম মুটিেক্সগুলি একটি কংক্রিটের উদাহরণ)।
  • নেটিভ থ্রেড হ্যান্ডেলটি পেতে একটি "পিছনের দরজা" উপস্থিত রয়েছে যাতে ক্লায়েন্টরা যদি চান তবে অন্তর্নিহিত ওএস ব্যবহার করে থ্রেডগুলি পরিচালনা করতে পারে।

এটি 2007 এর, তাই কিছু পয়েন্ট আর বৈধ নয়: boost::threadএখন একটি native_handleকার্যকারিতা রয়েছে, এবং মন্তব্যকারীরা উল্লেখ করেছেন যে, std::threadআর বাতিলকরণ নেই।

আমি boost::mutexএবং এর মধ্যে কোনও উল্লেখযোগ্য পার্থক্য খুঁজে পাইনি std::mutex


2
std::threadবাতিল নেই; এটা কি boost::threadযে!
অ্যান্টনি উইলিয়ামস

@ অ্যান্টনি আপনি কি নিশ্চিত যে আপনার interrupt()উত্সাহ: থ্রেডের অর্থ নেই এছাড়াও এটি প্রদর্শিত হয় যে এটি একটি আসল প্রস্তাব, যা 2007 এর পরে পরিবর্তিত হয়েছে
অ্যালেক্স বি

4
হ্যাঁ, বুস্টে বাতিলকরণকে "বাধা" বলা হয়। হ্যাঁ, এটি একটি পুরানো প্রস্তাব। সি ++ ১১ স্ট্যান্ডার্ডের সর্বশেষ সর্বজনীন খসড়া (যার মধ্যে থ্রেড লাইব্রেরি অন্তর্ভুক্ত) উন্মুক্ত-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf
অ্যান্টনি উইলিয়ামস

6

স্থানান্তর না করার একটি কারণ রয়েছে std::thread

আপনি যদি স্ট্যাটিক লিঙ্ক ব্যবহার করছেন তবে std::threadএই জিসিসি বাগ / বৈশিষ্ট্যগুলির কারণে অকেজো হয়ে ওঠে:

যেমন, আপনি যদি কল করেন std::thread::detachবা std::thread::joinএটি ব্যতিক্রম বা ক্রাশের দিকে নিয়ে যায়, যখন boost::threadএই ক্ষেত্রেগুলি ঠিক আছে।


আমি দেখতে পাচ্ছি যে একটি বাগ অনিশ্চিত এবং অন্যটি ইনভালিড, একটি মন্তব্যে এই প্রতিবেদকের বিরুদ্ধে লিঙ্ক করা উচিত ছিল libpthread.a। আপনি যা বলছেন তাতে আপনি কি সম্পূর্ণ নিশ্চিত?
einpoklum

1
@ আইনপোকলুম, আপনার এটি ব্যবহার করে এটি কার্যকর করতে সক্ষম হওয়া উচিত Wl,--whole-archive -lpthread -Wl,--no-whole-archive, উদাহরণস্বরূপ stackoverflow.com/a/23504509/72178 এই উত্তরটি দেখুন । তবে এটির সাথে লিঙ্ক করার খুব সোজা সোজা উপায় নয় libpthread.aএবং এটি খারাপ ধারণা হিসাবেও বিবেচিত হয়।
ks1322

4
আমরা কি ধরে নিতে পারি যে এই বাগগুলি এখন 2016 এর মতো স্থির হয়েছে? বাগগুলি 2012 সালে এবং জিসিসি ৪.৯.২ থেকে পোস্ট করা হয়েছিল, এটি আনুষ্ঠানিকভাবে সি ++ ১১ সমর্থন করে যাতে আমরা সরকারী সহায়তার আগে সি ++ 11 অভিযোগ করতে পারি না।
স্প্ল্যাশ

6

এন্টারপ্রাইজ কেস

আপনি যদি এমন উদ্যোগের জন্য এমন সফ্টওয়্যার লিখছেন যা মাঝারি থেকে বড় বিভিন্ন অপারেটিং সিস্টেমের উপর চালিত হয় এবং ফলস্বরূপ সেই অপারেটিং সিস্টেমে বিভিন্ন সংকলক এবং সংকলক সংস্করণ (বিশেষত তুলনামূলকভাবে পুরানো সংস্করণ) দিয়ে তৈরি করা হয় তবে আমার পরামর্শটি থেকে দূরে থাকুন আপাতত পুরোপুরি সি ++ 11। তার মানে আপনি ব্যবহার করতে পারবেন না std::thread, এবং আমি ব্যবহার করার পরামর্শ দেব boost::thread

বেসিক / টেক স্টার্টআপ কেস

আপনি যদি এক বা দুটি অপারেটিং সিস্টেমের জন্য লিখতে থাকেন তবে আপনি নিশ্চিতভাবেই জানেন যে আপনাকে কেবলমাত্র একটি আধুনিক সংকলক দিয়ে তৈরি করতে হবে যা বেশিরভাগ সি ++ 11 সমর্থন করে (যেমন ভিএস2015, জিসিসি 5.3, এক্সকোড 7), এবং আপনি ইতিমধ্যে নন বুস্ট লাইব্রেরির উপর নির্ভরশীল, তাহলে std::threadএকটি ভাল বিকল্প হতে পারে।

আমার অভিজ্ঞতা

আমি ব্যক্তিগতভাবে কঠোর, ভারীভাবে ব্যবহৃত, অত্যন্ত সামঞ্জস্যপূর্ণ, অত্যন্ত সামঞ্জস্যপূর্ণ লাইব্রেরি যেমন খুব আধুনিক বিকল্পের তুলনায় উত্সাহ দিতে আংশিক। থ্রেডিংয়ের মতো জটিল প্রোগ্রামিং বিষয়ের ক্ষেত্রে এটি বিশেষত সত্য। এছাড়াও, আমি দীর্ঘকালীন boost::threadপরিবেশ, সংকলক, থ্রেডিং মডেল ইত্যাদির বিস্তৃত অ্যারে জুড়ে (এবং সাধারণভাবে উত্সাহিতকরণ) দিয়ে দুর্দান্ত সাফল্য পেয়েছি যখন এটি আমার পছন্দ, আমি বুস্ট নির্বাচন করি।


1
@ উমনিয়োব যদিও তিনি ঠিক আছেন। সি ++ 11 থ্রেডিংয়ের অনেকগুলি বাস্তবায়ন এতটাই ভেঙে গেছে আমি অবাক হয়েছি এমনকি লোকেরা এটি ব্যবহার করার বিষয়টি বিবেচনা করে।
স্টেসিগার্ল


1

সিডি +: 17 এর সাথে ভাগ করা_মিটেক্স সি ++ 17 এ যুক্ত হয়েছে added

এখানে অন্যান্য উত্তরগুলি সাধারণভাবে পার্থক্যগুলির একটি খুব ভাল ওভারভিউ সরবরাহ করে। তবে, std::shared_mutexএই উত্সাহ সমাধানের সাথে বেশ কয়েকটি সমস্যা রয়েছে ।

  1. আপগ্রেডযোগ্য মিউটিস এগুলি থেকে অনুপস্থিত std::thread। তারা একটি পাঠক লেখক আপগ্রেড করা করার অনুমতি দেয় অন্য কোন লেখক আপনি আগে পেতে সক্ষম হবেন ছাড়া । এগুলি আপনাকে প্রাক-প্রক্রিয়াজাতকরণের মতো বৃহত গণনা (উদাহরণস্বরূপ, কোনও ডেটা স্ট্রাকচারের পুনর্নির্মাণ) যেমন পড়ার মোডে রাখে তখন কেবলমাত্র অল্প সময়ের জন্য রাইটিং লক ধরে রেখে পুনর্নির্দেশ প্রয়োগ করতে লিখতে আপগ্রেড করুন।

  2. ফর্সা। আপনার যদি একটি এর সাথে অবিচ্ছিন্নভাবে পড়া কার্যকলাপ থাকে তবে std::shared_mutexআপনার লেখকরা অনির্দিষ্টকালের জন্য সফটলকড হয়ে যাবেন। এটি কারণ অন্য পাঠক যদি আসে তবে তাদের সর্বদা অগ্রাধিকার দেওয়া হবে। সহ boost:shared_mutex, সমস্ত থ্রেড অবশেষে অগ্রাধিকার দেওয়া হবে । (1) পাঠক বা লেখক কেউই অনাহারী হবে না।

এর tl; dr হ'ল যদি আপনার খুব ডাউন-টাইম এবং খুব উচ্চতর বিতর্ক না করে খুব হাই-থ্রুপুট সিস্টেম থাকে তবে std::shared_mutexএটির উপরে অগ্রাধিকার সিস্টেমটি নিজে তৈরি না করে কখনও আপনার পক্ষে কাজ করবে না। boost::shared_mutexবাক্সটির বাইরে কাজ করবে, যদিও আপনাকে এটি কিছু ক্ষেত্রে ঝুঁকির প্রয়োজন হতে পারে। আমি যুক্তি দেব যে std::shared_mutexআচরণটি একটি সুপ্ত বাগ যা বেশিরভাগ কোডে এটি ব্যবহার করার জন্য অপেক্ষা করে।

(1) প্রকৃত অ্যালগরিদম এটি ব্যবহার করে অপারেটিং সিস্টেম থ্রেড নির্ধারণকারী উপর ভিত্তি করে। আমার অভিজ্ঞতায়, যখন পাঠগুলি স্যাচুরেটেড হয়, উইন্ডোজ ওএসএক্স / লিনাক্সের চেয়ে লম্বা বিরতি (লেখার লক পাওয়ার সময়) থাকে।


0

আমি বুস্টের পরিবর্তে স্ট্যান্ড থেকে শেয়ারড_পিটার ব্যবহার করার চেষ্টা করেছি এবং এই ক্লাসটির জিসিসি বাস্তবায়নে আমি একটি বাগ খুঁজে পেয়েছি। আমার অ্যাপ্লিকেশনটি দুবার কলকারী ধ্বংসকারীদের কারণে ক্রাশ হচ্ছে (এই শ্রেণীটি থ্রেড-নিরাপদ হওয়া উচিত এবং এ জাতীয় সমস্যা তৈরি করা উচিত নয়)। উত্সাহিত করার পরে :: শেয়ারড_পিটার সমস্ত সমস্যা অদৃশ্য হয়ে গেল। সি ++ 11 এর বর্তমান বাস্তবায়ন এখনও পরিপক্ক নয়।

বুস্টের আরও বৈশিষ্ট্য রয়েছে। উদাহরণস্বরূপ স্টাডি সংস্করণে শিরোনাম কোনও স্ট্রিমকে সিরিয়ালাইজার সরবরাহ করে না (অর্থাত্ cout << সময়কাল)। বুস্টের অনেকগুলি লাইব্রেরি রয়েছে যা নিজস্ব, ইত্যাদি সমতুল্য ব্যবহার করে তবে স্টাডি সংস্করণগুলিতে সহযোগিতা করে না।

সংক্ষেপে - আপনার যদি ইতিমধ্যে বুস্ট ব্যবহার করে কোনও অ্যাপ্লিকেশন লেখা থাকে তবে আপনার কোডটি সি ++ 11 স্ট্যান্ডার্ডে যাওয়ার ক্ষেত্রে কিছুটা চেষ্টা করার পরিবর্তে এটি রাখা নিরাপদ।


4
shared_ptrবিনাশকারী থ্রেড-নিরাপদ হতে হবে না, এটি এর অনির্ধারিত আচরণ একটি থ্রেড একটি বস্তু অ্যাক্সেস যখন অন্য থ্রেড এটা ধ্বংস করছে আছে। আপনি যদি ভাবেন যে আপনি জিসিসির শেয়ারড_প্টারে একটি বাগ পেয়েছেন দয়া করে এটির প্রতিবেদন করুন , অন্যথায় আপনি সম্ভাবনার ভারসাম্যকে ভুলভাবে ব্যবহার করছেন।
জোনাথন ওয়েকেলি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.