আমার সংকলকটি আমার অব্যবহৃত স্থিত থ্রেড_লোকাল ক্লাস সদস্যকে উপেক্ষা করেছে?


10

আমি আমার ক্লাসে কিছু থ্রেড রেজিস্ট্রেশন করতে চাই, তাই আমি thread_localবৈশিষ্ট্যটির জন্য একটি চেক যুক্ত করার সিদ্ধান্ত নিয়েছি :

#include <iostream>
#include <thread>

class Foo {
 public:
  Foo() {
    std::cout << "Foo()" << std::endl;
  }
  ~Foo() {
    std::cout << "~Foo()" << std::endl;
  }
};

class Bar {
 public:
  Bar() {
    std::cout << "Bar()" << std::endl;
    //foo;
  }
  ~Bar() {
    std::cout << "~Bar()" << std::endl;
  }
 private:
  static thread_local Foo foo;
};

thread_local Foo Bar::foo;

void worker() {
  {
    std::cout << "enter block" << std::endl;
    Bar bar1;
    Bar bar2;
    std::cout << "exit block" << std::endl;
  }
}

int main() {
  std::thread t1(worker);
  std::thread t2(worker);
  t1.join();
  t2.join();
  std::cout << "thread died" << std::endl;
}

কোডটি সহজ। আমার Barক্লাসে একটি স্থির thread_localসদস্য আছে foo। যদি একটি স্ট্যাটিক thread_local Foo fooতৈরি করা হয়, এর অর্থ একটি থ্রেড তৈরি হয়েছে।

তবে আমি কোডটি চালানোর সময়, Foo()প্রিন্টগুলির মধ্যে কিছুই নেই এবং যদি আমি Barএর কনস্ট্রাক্টরের মন্তব্যটি সরিয়ে ফেলি , যা ব্যবহার করে foo, কোডটি ঠিক কাজ করে।

আমি এটি জিসিসি (.4.৪.০) এবং কলং (on.০.০) এ চেষ্টা করেছি এবং ফলাফলগুলি একই are আমি অনুমান করি যে সংকলকটি আবিষ্কার করেছে fooযা অব্যবহৃত এবং কোনও উদাহরণ উত্পন্ন করে না। সুতরাং

  1. সংকলক static thread_localসদস্যকে উপেক্ষা করেছে ? আমি কীভাবে এটির জন্য ডিবাগ করতে পারি?
  2. যদি তা হয় তবে একজন সাধারণ staticসদস্যের কেন এই সমস্যা নেই?

উত্তর:


9

আপনার পর্যবেক্ষণে কোনও সমস্যা নেই। [বেসিক.স্টি.স্ট্যাটিক] / 2 স্থিতিশীল স্টোরেজ সময়কাল সহ ভেরিয়েবলগুলি অপসারণ নিষিদ্ধ করে:

স্ট্যাটিক স্টোরেজ সময়কাল সহ কোনও পরিবর্তনশীলটির যদি আরম্ভ হয় বা পার্শ্ব প্রতিক্রিয়াযুক্ত কোনও ডেস্ট্রাক্টর থাকে তবে এটি অপব্যবহারযোগ্য বলে মনে হলেও তা অপসারণ করা হবে না, ব্যতীত কোনও শ্রেণি অবজেক্ট বা তার অনুলিপি / পদক্ষেপ [ক্লাসকপি] এ উল্লিখিত হিসাবে মুছে ফেলা হতে পারে except ।

এই সীমাবদ্ধতা অন্য সঞ্চয়স্থানের সময়কালগুলির জন্য উপস্থিত নেই। প্রকৃতপক্ষে, [বেসিক.এসটিসি। থ্রেড] / 2 বলেছেন:

থ্রেড স্টোরেজ সময়কাল সহ একটি পরিবর্তনশীল এর প্রথম অদ্বিতীয় ব্যবহারের আগে আরম্ভ করা হবে এবং যদি এটি নির্মিত হয় তবে থ্রেড প্রস্থানের সময় ধ্বংস হয়ে যাবে।

এটি পরামর্শ দেয় যে থ্রেড স্টোরেজ সময়কাল সহ একটি ভেরিয়েবল গন্ধযুক্ত-ব্যবহৃত না হলে নির্মাণ করা দরকার।


তবে কেন এই তাত্পর্য?

স্ট্যাটিক স্টোরেজ সময়কাল জন্য, প্রোগ্রাম প্রতি পরিবর্তনশীল একটি মাত্র উদাহরণ আছে। এর নির্মাণের পার্শ্ব প্রতিক্রিয়াগুলি তাৎপর্যপূর্ণ হতে পারে (প্রোগ্রাম-ওয়াইড কনস্ট্রাক্টরের মতো কিন্ডা), তাই এর পার্শ্ব প্রতিক্রিয়াগুলি প্রয়োজন।

থ্রেড স্থানীয় স্টোরেজ সময়কাল জন্য, তবে, একটি সমস্যা আছে: একটি অ্যালগোরিদম অনেক থ্রেড শুরু করতে পারে। এই থ্রেডগুলির বেশিরভাগের জন্য ভেরিয়েবল সম্পূর্ণ অপ্রাসঙ্গিক। এটি হাসিখুশি হবে যদি একটি বাহ্যিক পদার্থবিজ্ঞানের সিমুলেশন লাইব্রেরি কল করে যা std::reduce(std::execution::par_unseq, first, last)প্রচুর fooদৃষ্টান্ত তৈরি করে , তাই না?

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


1
ঠিক আছে ... স্ট্যান্ডার্ড যদি তাই বলে থাকে তবে তা হতে পারে ... তবে কমিটি কী অদ্ভুত নয় পার্শ্ব প্রতিক্রিয়াটিকে স্থির স্টোরেজ সময়কাল হিসাবে বিবেচনা করে না?
রেভেনিসডেস্ক

@reavenisadesk আপডেট উত্তর দেখুন।
এলএফ

1

আমি " ELF হ্যান্ডলিং ফর থ্রেড-লোকাল স্টোরেজ " এ এই তথ্যটি পেয়েছি যা @ এলএফ এর উত্তর প্রমাণ করতে পারে

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.