আমি কীভাবে সি ++ 11 এ থ্রেডটি শেষ করব?


137

থ্রেডটি সঠিকভাবে শেষ করার দরকার নেই, বা এটি একটি "সমাপ্তি" কমান্ডকে সাড়া দেওয়ার দরকার নেই। আমি খাঁটি সি ++ 11 ব্যবহার করে শক্তভাবে থ্রেডটি বন্ধ করতে আগ্রহী।


7
এখানে এই বিষয়ে ভাল প্রশ্ন: স্ট্যাকওভারফ্লো / প্রশ্ন / 2790346 / c0x-thread-interration "সমস্ত ভাষার স্পেসিফিকেশন বলে যে সমর্থনটি ভাষাতে নির্মিত হয়নি"
নেমানজা বোরিক

উত্তর:


137
  1. আপনি যে std::terminate()কোনও থ্রেড থেকে কল করতে পারেন এবং যে থ্রেডটি আপনি উল্লেখ করছেন সেটি জোর করে শেষ হবে।

  2. আপনি ~thread()লক্ষ্য থ্রেডের অবজেক্টে কোনও হস্তক্ষেপ ছাড়াই join()বা সেই বস্তুতে মৃত্যুদণ্ড কার্যকর করার ব্যবস্থা করতে পারেন detach()। এটি বিকল্প 1 এর মতোই প্রভাব ফেলবে।

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

বিকল্প 1 এবং 2 ইনট্রা-প্রক্রিয়া সংস্থানগুলি ফাঁস করে না, তবে তারা প্রতিটি থ্রেড সমাপ্ত করে

বিকল্প 3 সম্ভবত সম্পদ ফাঁস করবে, তবে লক্ষ্য থ্রেড ব্যতিক্রমটি ছুঁতে সম্মত হতে হবে তাতে আংশিকভাবে সহযোগিতা রয়েছে।

একাধিক থ্রেড প্রোগ্রামে (অর্থাত্ সমস্ত থ্রেড না মেরে) অসহযোগিতামূলকভাবে একটি থ্রেডকে মেরে ফেলার জন্য সি ++ 11 এ (যে সম্পর্কে আমি অবগত রয়েছি) কোনও পোর্টেবল উপায় নেই। এই জাতীয় বৈশিষ্ট্যটি নকশা করার জন্য কোনও প্রেরণা ছিল না।

এ এর std::threadএই সদস্যের কাজ থাকতে পারে:

native_handle_type native_handle();

আপনি যা চান তা করতে কোনও OS- নির্ভর ফাংশন কল করতে আপনি এটি ব্যবহার করতে সক্ষম হতে পারেন। অ্যাপলের ওএসের উদাহরণস্বরূপ, এই ফাংশনটি বিদ্যমান এবং native_handle_typeএটি একটি pthread_t। আপনি যদি সফল হন তবে আপনার সম্পদ ফাঁস হওয়ার সম্ভাবনা রয়েছে।


2
উপর থেকে একটু nitpick "ভিতরে-প্রক্রিয়া সম্পদ লিক না" : যদিও এটা সত্যি অবশ্যই হয় যা OS প্রক্রিয়া হত্যার পর সমস্ত সম্পদ সংশোধন করবে সম্পদ করছে যতদূর প্রোগ্রাম সংশ্লিষ্ট হয় ফাঁস। এটি সাধারণত অপ্রাসঙ্গিক, তবে এখনও কিছু ক্ষেত্রে এটি একটি সমস্যা হতে পারে। std::terminateস্ট্যাটিক ডেস্ট্রাক্টরকে না ডাকে বা এটি আউটপুট বাফারগুলিকে ফ্লাশ করে না, সুতরাং যে সংস্থানগুলিতে সংস্থানগুলি প্রকাশ করা হয় তা ক্রম-সংজ্ঞায়িত নয়, বা আপনার কোনও ডেটা ব্যবহারকারীর কাছে দৃশ্যমান বা স্থায়ী স্টোরের কাছে লিখিত আছে বা এমনকী কোনও গ্যারান্টিও নেই have ধারাবাহিক এবং সম্পূর্ণ।
দামন

6
আপনি একই কল exit()বা কল করতে পারেন abort()একই সামগ্রিক প্রভাব।
এন। 'সর্বনাম' মি।

2
# 1 টি একটি রসিকতা এবং @ ক্রিসডডড সঠিক। জোকটি উত্তরটিতে # 3 এর অধীনে প্রথম বাক্যে ব্যাখ্যা করা হয়েছে। এছাড়াও ন্যান্নো ল্যাংস্ট্র্যাট এর উত্তর এবং এর নীচে মন্তব্যগুলি দেখুন।
হাওয়ার্ড হিন্যান্ট

43

@ হর্ন্টের উত্তরটি সঠিক এবং বিস্তৃত। তবে এটি খুব দ্রুত পড়লে ভুল বোঝাবুঝি হতে পারে, কারণ std::terminate()(সম্পূর্ণ প্রক্রিয়া) @ আলেকজান্ডারভিএক্সের (1 থ্রেড) মনে যে "সমাপ্তি" হিসাবে একই নাম রয়েছে বলে মনে হয়।

সংক্ষিপ্তসার: "জোর করে 1 থ্রেড সমাপ্ত করুন (টার্গেট থ্রেড সহযোগিতা করে না) + খাঁটি সি ++ 11 = কোনও উপায় নেই" "


14
আহ, আমার # 1 সত্যিই মজার। আপনি কোন থ্রেড জোর করে শেষ করতে চান তা নির্দিষ্ট করতে হবে না। সিস্টেমটি যাদুকরীভাবে জানে যে আপনি কোনটি জোর করে শেষ করতে চান এবং এটি করেন!
হাওয়ার্ড হিন্যান্ট

8
হ্যাঁ, std::terminate()উত্তরটি ক্লাসিক দুষ্টু ডিজন গল্পের মতো; এটি চিঠির ওপির ইচ্ছা অনুযায়ী সমস্ত কিছু পূরণ করে, যদিও সম্ভবত তিনি বোঝাতে চেয়েছিলেন না । অপ্রচলিত রসিকতা আমাকে হাসিয়ে তুলেছিল। :-)
ন্যান্নো ল্যাংস্ট্র্যাট

2
কেবল নির্দোষ সি ++ নবীকে তাদের প্রত্যাশা খুব বেশি / দীর্ঘায়িত হতে আটকাতে হবে।
ন্যান্নো ল্যাংস্ট্র্যাট 1

2
মার্জিতভাবে বর্ণিত। :-)
হাওয়ার্ড হিন্যান্ট

@ ন্যানো ল্যাংস্ট্র্যাট দম্মনিত ... আমি পড়ার আগ পর্যন্ত আমার এইরকম উচ্চ প্রত্যাশা ছিল: (..আমিও, ওহ ভাল + চারপাশে: 1):
কোড_ফড্ডার

13

এই প্রশ্নের প্রকৃতপক্ষে আরও গভীর প্রকৃতি রয়েছে এবং সাধারণভাবে মাল্টিথ্রেডিং ধারণাগুলি সম্পর্কে ভাল ধারণা আপনাকে এই বিষয় সম্পর্কে অন্তর্দৃষ্টি প্রদান করবে। আসলে এমন কোন ভাষা বা কোনও অপারেটিং সিস্টেম নেই যা আপনাকে অ্যাসিক্রোনাস হঠাৎ করে থ্রেড সমাপ্তির জন্য সুযোগগুলি সরবরাহ না করে সেগুলি ব্যবহার না করার সতর্কতা ছাড়াই। এবং এই সমস্ত কার্যকরকরণ পরিবেশগুলি দৃ strongly়ভাবে বিকাশকারীকে পরামর্শ দেয় এমনকি সমবায় বা সিঙ্ক্রোনাস থ্রেড সমাপ্তির ভিত্তিতে মাল্টিথ্রেডিং অ্যাপ্লিকেশনগুলি তৈরি করতে পারে। এই সাধারণ সিদ্ধান্ত এবং পরামর্শগুলির কারণ হ'ল এগুলি সমস্ত একই সাধারণ মাল্টিথ্রেডিং মডেলের ভিত্তিতে নির্মিত।

আসুন মাল্টিপ্রসেসিং এবং মাল্টিথ্রেডিং ধারণার তুলনা করি দ্বিতীয়টির সুবিধাগুলি এবং সীমাবদ্ধতাগুলি আরও ভালভাবে বুঝতে understand

মাল্টিপ্রসেসিং পুরো কার্যকর পরিবেশের বিভাজনকে অপারেটিং সিস্টেম দ্বারা নিয়ন্ত্রিত সম্পূর্ণ বিচ্ছিন্ন প্রক্রিয়াগুলির সেট হিসাবে ধরে নেয়। প্রক্রিয়া স্থানীয় অভ্যন্তরের প্রক্রিয়া এবং এর ভিতরে থাকা ডেটা এবং সমস্ত সিস্টেম সংস্থান যেমন ফাইল, সকেট, সিঙ্ক্রোনাইজেশন অবজেক্ট সহ কার্যকরকরণ পরিবেশের রাষ্ট্রকে অন্তর্ভুক্ত করে এবং বিচ্ছিন্ন করে। বিচ্ছিন্নতা প্রক্রিয়াটির একটি সমালোচনামূলকভাবে গুরুত্বপূর্ণ বৈশিষ্ট্য, কারণ এটি প্রক্রিয়া সীমানা দ্বারা ত্রুটি প্রচারকে সীমাবদ্ধ করে। অন্য কথায়, কোনও একটি প্রক্রিয়া সিস্টেমের অন্য কোনও প্রক্রিয়ার সামঞ্জস্যতাকে প্রভাবিত করতে পারে না। প্রক্রিয়া আচরণের ক্ষেত্রেও এটি একই তবে কম সীমাবদ্ধ এবং আরও ঝাপসা উপায়। এই জাতীয় পরিবেশে যে কোনও প্রক্রিয়া যে কোনও "স্বেচ্ছাচারী" মুহুর্তে মারা যেতে পারে, কারণ প্রথমত প্রতিটি প্রক্রিয়া বিচ্ছিন্ন হয়, দ্বিতীয়ত,

বিপরীতে, মাল্টিথ্রেডিং একই প্রক্রিয়াতে একাধিক থ্রেড চালাচ্ছে। তবে এই সমস্ত থ্রেড একই বিচ্ছিন্ন বাক্সটি ভাগ করে নেয় এবং প্রক্রিয়াটির অভ্যন্তরীণ অবস্থার কোনও অপারেটিং সিস্টেম নিয়ন্ত্রণ নেই। ফলস্বরূপ যে কোনও থ্রেড বৈশ্বিক প্রক্রিয়া রাষ্ট্রের পাশাপাশি এটি দূষিত করতে সক্ষম। একই মুহুর্তে যে পয়েন্টগুলিতে থ্রেডের অবস্থা থ্রেডকে হত্যা করতে নিরাপদ হিসাবে পরিচিত তা পুরোপুরি প্রয়োগের যুক্তির উপর নির্ভর করে এবং এটি অপারেটিং সিস্টেমের জন্য বা প্রোগ্রামিং ল্যাঙ্গুয়েজ রানটাইমের জন্যও পরিচিত নয়। ফলস্বরূপ স্বেচ্ছাচারী মুহুর্তে থ্রেড সমাপ্তির অর্থ হ'ল এটির মৃত্যুদন্ড কার্যকর করার পথে নির্বিচারে বিন্দুতে হত্যা করা এবং প্রক্রিয়া-ব্যাপী ডেটা দুর্নীতি, স্মৃতিশক্তি এবং ফুটো হ্যান্ডেলগুলি সহজেই পরিচালিত করতে পারে,

এর কারণে সাধারণ পদ্ধতির বিকাশকারীদেরকে সিঙ্ক্রোনাস বা সমবায় থ্রেড সমাপ্তি প্রয়োগ করতে বাধ্য করা হয়, যেখানে এক থ্রেড অন্য থ্রেড সমাপ্তির অনুরোধ করতে পারে এবং অন্যান্য থ্রেডটি সুস্পষ্টভাবে নির্ধারিত বিন্দুতে এই অনুরোধটি পরীক্ষা করতে পারে এবং ভাল-সংজ্ঞায়িত রাষ্ট্র থেকে শাটডাউন প্রক্রিয়া শুরু করতে পারে নিরাপদে এবং ধারাবাহিক উপায়ে সমস্ত বিশ্বব্যাপী সিস্টেম-বিস্তৃত সংস্থান এবং স্থানীয় প্রক্রিয়া-বিস্তৃত সংস্থানগুলি মুক্ত করার সাথে।


7
এটি খুব সহায়ক উত্তর নয়। মাল্টি-প্রসেসিং এখানে প্রাসঙ্গিক নয় এবং মাল্টি-থ্রেডিং সম্পর্কে পর্যবেক্ষণগুলি বরং বিস্তৃত।
এমসাল্টাররা

4
আমি যা বলতে চাইছিলাম এবং বিশদে যা বলেছিলাম তা হ'ল মাল্টিথ্রেডিং মডেল জোরালো থ্রেড সমাপ্তির আনুষ্ঠানিক উপায় সরবরাহ করে না। সি ++ মেমরির মডেল, মাল্টিথ্রেডিং মডেল ইত্যাদি সহ পরিষ্কার মডেলগুলি অনুসরণ করতে চায় force জোর করে থ্রেড সমাপ্তির পদ্ধতি সহজাতভাবে অনিরাপদ। যদি সি ++ স্ট্যান্ডার্ড কমিটি এটিকে সি ++ এ যুক্ত করতে বাধ্য করা হয়, তবে এটি পরবর্তী বিবৃতি দিয়ে তৈরি করা হবে "পদ্ধতিটি সমাপ্তি (থ্রেড এক্সিকিউশন () থ্রেড এক্সিকিউশনটি সমাপ্ত করে und আচরণের অপরিজ্ঞাত।") যা "কিছু ম্যাজিক তৈরি করা এবং সম্ভবত থ্রেডটি বন্ধ করে দেওয়ার মত শব্দ হবে" sound "।
জারাথুস্ট্রআ

সি # এর এই বৈশিষ্ট্য রয়েছে।
ডায়াফ স্ক্রেন

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

11

সি ++ থ্রেডটি শেষ করতে ওএস-নির্ভরশীল ফাংশনটি ব্যবহারের টিপস:

  1. std::thread::native_handle()কল করার আগে কেবল থ্রেডের বৈধ নেটিভ হ্যান্ডেল প্রকারটি পেতে পারে join()বা detach()। এর পরে, native_handle()0 - রিটার্নগুলি pthread_cancel()কর্কশ হবে।

  2. নেটিভ থ্রেড টার্মিনেশন ফাংশনকে কার্যকরভাবে কল করতে (যেমন pthread_cancel()), কল করার আগে আপনাকে নেটিভ হ্যান্ডেলটি সংরক্ষণ করতে হবে std::thread::join()বা std::thread::detach()। যাতে আপনার নেটিভ টার্মিনেটরের সর্বদা ব্যবহারের জন্য একটি বৈধ নেটিভ হ্যান্ডেল থাকে।

আরও ব্যাখ্যা দয়া করে এখানে দেখুন: http://bo-yang.github.io/2017/11/19/cpp-kill-detached-thread


5

আমার ধারণা, যে থ্রেডটি মারতে হবে তা হয় কোনও ধরণের ওয়েটিং মোডে বা কোনও ভারী কাজ করা doing আমি একটি "নিষ্পাপ" উপায় ব্যবহার করার পরামর্শ দেব।

কিছু গ্লোবাল বুলিয়ান সংজ্ঞায়িত করুন:

std::atomic_bool stop_thread_1 = false;

নিম্নলিখিত কোডটি (বা অনুরূপ) বেশ কয়েকটি মূল পয়েন্টে রাখুন, যাতে থ্রেডটি স্বাভাবিকভাবে শেষ না হওয়া অবধি কল স্ট্যাকের সমস্ত ফাংশন ফিরে আসবে:

if (stop_thread_1)
    return;

তারপরে অন্য (প্রধান) থ্রেড থেকে থ্রেডটি থামাতে:

stop_thread_1 = true;
thread1.join ();
stop_thread_1 = false; //(for next time. this can be when starting the thread instead)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.