রেসের অবস্থা কী?


980

মাল্টিথ্রেডেড অ্যাপ্লিকেশনগুলি লেখার সময়, সবচেয়ে সাধারণ সমস্যাগুলির মধ্যে একটি হল জাতিদের শর্ত।

সম্প্রদায়ের কাছে আমার প্রশ্নগুলি হ'ল:

রেসের অবস্থা কী?
আপনি তাদের সনাক্ত করতে পারেন?
কিভাবে আপনি তাদের হ্যান্ডেল করবেন?
অবশেষে, আপনি কীভাবে তাদের সংঘটিত হতে বাধা দেন?


3
লিনাক্স হাটো এর সিকিউর প্রোগ্রামিং-এর একটি দুর্দান্ত অধ্যায় রয়েছে যা সেগুলি কী কী এবং কীভাবে সেগুলি এড়ানো যায় সে সম্পর্কে বর্ণনা করে।
ক্রেগ এইচ

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

@MikeMB। বাইট কোড এক্সিকিউশন বিশ্লেষণ করা ছাড়া, যেমন রেস ক্যাচার দ্বারা সম্পন্ন হয়েছে (কেবল এই থ্রেড স্ট্যাকওভারফ্লো.com/a/29361427/1363844 দেখুন ) আমরা বাইট কোডের সাথে সংকলিত প্রায় languages২ টি ভাষাকে সম্বোধন করতে পারি ( এন.ইউইকিপিডিয়া.আর্গ দেখুন ) / উইকি / লিস্ট_এফ_জেভিএম_এলংয়েজস )
বেন

উত্তর:


1236

দুটি বা ততোধিক থ্রেড ভাগ করা ডেটা অ্যাক্সেস করতে পারে এমন সময় একটি দৌড়ের অবস্থা ঘটে এবং তারা একই সাথে এটি পরিবর্তন করার চেষ্টা করে। যেহেতু থ্রেড শিডিয়ুলিং অ্যালগরিদম যে কোনও সময় থ্রেডগুলির মধ্যে অদলবদল করতে পারে, তাই থ্রেডগুলি ভাগ করে নেওয়া ডেটা অ্যাক্সেস করার চেষ্টা করবে threads সুতরাং, ডেটা পরিবর্তনের ফলাফল থ্রেড শিডিয়ুলিং অ্যালগরিদমের উপর নির্ভরশীল, অর্থাত উভয় থ্রেড ডেটা অ্যাক্সেস / পরিবর্তন করতে "রেসিং" করছে।

সমস্যাগুলি প্রায়শই দেখা দেয় যখন একটি থ্রেড "চেক-এর-পরে-অ্যাক্ট" করে (উদাহরণস্বরূপ "চেক" মানটি X হয়, তবে মানটি X এর উপর নির্ভর করে এমন কিছু করার জন্য "কাজ করুন") এবং অন্য থ্রেড মানটিতে কিছু করে "চেক" এবং "আইন" এর মধ্যে। উদাহরণ:

if (x == 5) // The "Check"
{
   y = x * 2; // The "Act"

   // If another thread changed x in between "if (x == 5)" and "y = x * 2" above,
   // y will not be equal to 10.
}

বিন্দুটি হ'ল, y 10 হতে পারে বা চেক এবং অ্যাক্টের মধ্যে অন্য থ্রেড x পরিবর্তন হয়েছে কিনা তার উপর নির্ভর করে এটি কিছু হতে পারে। আপনার জানার কোনও আসল উপায় নেই।

প্রতিযোগিতামূলক পরিস্থিতি যাতে না ঘটে তা প্রতিরোধ করার জন্য, আপনি একবারে কেবলমাত্র একটি থ্রেড ডেটা অ্যাক্সেস করতে পারবেন তা নিশ্চিত করার জন্য আপনি সাধারণত ভাগ করা ডেটাগুলির চারপাশে একটি লক রাখতেন। এর অর্থ এইরকম কিছু হবে:

// Obtain lock for x
if (x == 5)
{
   y = x * 2; // Now, nothing can change x until the lock is released. 
              // Therefore y = 10
}
// release lock for x

121
যখন অন্য থ্রেডটি লকটির মুখোমুখি হয় তখন কী করবে? এটা অপেক্ষা? ত্রুটি?
ব্রায়ান আরটিজ

173
হ্যাঁ, অন্য থ্রেডটি এগিয়ে যাওয়ার আগে লকটি প্রকাশ না হওয়া পর্যন্ত অপেক্ষা করতে হবে। এটি খুব গুরুত্বপূর্ণ করে তোলে যে লকটি হোল্ডিং থ্রেডটি শেষ হয়ে গেলে এটিটি প্রকাশ করা হয়। যদি এটি কখনই এটি প্রকাশ না করে, তবে অন্য থ্রেডটি অনির্দিষ্টকালের জন্য অপেক্ষা করবে।
লেহানে

2
@ ইয়ান একটি বহুবিবাহিত সিস্টেমে সর্বদা সময় আসবে যখন সংস্থানগুলি ভাগ করা দরকার। একথা বলার অপেক্ষা রাখে যে বিকল্প না দিয়ে একটি পন্থা খারাপ, কেবল উত্পাদনশীল নয়। আমি সর্বদা উন্নতি করার উপায়গুলি খুঁজছি এবং যদি এর বিকল্প থাকে তবে আমি আনন্দের সাথে এটি অনুসন্ধান করব এবং প্রো ও কনসটি ওজন করব।
ডেস্পের্টারে

2
@ ডেস্পার্টার ... এছাড়াও, এটি অবশ্যই প্রয়োজনীয় নয় যে সম্পদগুলি সর্বদা মিলটি-থ্রেড সিস্টেমে ভাগ করা প্রয়োজন। উদাহরণস্বরূপ আপনার একটি অ্যারে থাকতে পারে যেখানে প্রতিটি উপাদানটির প্রক্রিয়াজাতকরণ প্রয়োজন। আপনি সম্ভবত অ্যারে বিভাজন করতে পারেন এবং প্রতিটি বিভাজনের জন্য একটি থ্রেড রাখতে পারেন এবং থ্রেডগুলি একে অপরের থেকে সম্পূর্ণ স্বাধীনভাবে তাদের কাজ করতে পারে।
ইয়ান ওয়ারবার্টন

12
একটি দৌড় দেখা দেওয়ার জন্য এটি যথেষ্ট যে একটি একক থ্রেড ভাগ করা ডেটা পরিবর্তন করার চেষ্টা করে যখন বাকী থ্রেডগুলি হয় পড়তে বা পরিবর্তন করতে পারে।
সোমবারউইটিউজারনেম

213

একটি "রেস শর্ত" বিদ্যমান যখন মাল্টিথ্রেডেড (বা অন্যথায় সমান্তরাল) কোড যা একটি ভাগ করা সংস্থান অ্যাক্সেস করবে এমনভাবে এমনভাবে করতে পারে যাতে অপ্রত্যাশিত ফলাফল হতে পারে।

এই উদাহরণটি ধরুন:

for ( int i = 0; i < 10000000; i++ )
{
   x = x + 1; 
}

যদি আপনার 5 টি থ্রেড একবারে এই কোডটি কার্যকর করে থাকে তবে এক্স এর মান 50,000,000 না হওয়া পর্যন্ত শেষ হবে। এটি আসলে প্রতিটি রানের সাথে আলাদা হয়।

এটি কারণ, প্রতিটি থ্রেডের এক্সের মান বাড়ানোর জন্য তাদের নিম্নলিখিতটি করতে হবে: (সরল, স্পষ্টতই)

এক্স এর মান পুনরুদ্ধার করুন
এই মান 1 যোগ করুন
এই মানটি এক্সে সঞ্চয় করুন

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

ধরা যাক একটি থ্রেড x এর মান পুনরুদ্ধার করে তবে এটি এখনও সংরক্ষণ করে না। অন্য একটি থ্রেডও একই মানের x এর পুনরুদ্ধার করতে পারে (কারণ কোনও থ্রেড এখনও এটি পরিবর্তন করে নি) এবং তারপরে তারা উভয়ই একই মান (x + 1) x এ ফিরে সংরক্ষণ করবে !

উদাহরণ:

থ্রেড 1: এক্স পড়ছে, মান 7
থ্রেড 1: 1 এ x যুক্ত করুন, মান এখন 8
থ্রেড 2: এক্স পড়ছে, মান 7
থ্রেড 1: স্টোর 8 এক্স
থ্রেড 2: 1 এ x যুক্ত করে, মান এখন 8
থ্রেড 2: 8 এক্স এক্স

ভাগ করা সংস্থান অ্যাক্সেস করে এমন কোডের আগে কোনও ধরণের লকিং প্রক্রিয়া নিযুক্ত করে রেসের পরিস্থিতি এড়ানো যেতে পারে :

for ( int i = 0; i < 10000000; i++ )
{
   //lock x
   x = x + 1; 
   //unlock x
}

এখানে, উত্তরটি প্রতিবার 50,000,000 হিসাবে আসে।

লকিংয়ের বিষয়ে আরও তথ্যের জন্য: সন্ধান করুন: মিটেক্স, সেমফোর, সমালোচনা বিভাগ, ভাগ করা সংস্থান।


এই জাতীয় জিনিসগুলি কীভাবে খারাপ হয় তা পরীক্ষা করার জন্য একটি প্রোগ্রামের উদাহরণের জন্য jakob.engbloms.se/archives/65 দেখুন ... এটি আপনি যে মেশিনটি চালাচ্ছেন তার মেমরির মডেলের উপর নির্ভর করে।
jakobengblom2

1
এটি যদি এক কোটির কোটিতে থামতে হয় তবে এটি কীভাবে পঞ্চাশ কোটিতে যাবে?

9
@ নোকমপ্রেন্ডে: 5 টি থ্রেড একই সময়ে একই কোড সম্পাদন করে, যেমন স্নিপেটের নীচে সরাসরি বর্ণনা করা হয়েছে ...
জন স্কিটি

4
@ জনস্কিট আপনি ঠিক বলেছেন, আমি এবং এক্সকে বিভ্রান্ত করেছি। ধন্যবাদ.

সিঙ্গেলটন প্যাটার্ন বাস্তবায়নে ডাবল চেক লক করা জাতি শর্ত রোধ করার একটি উদাহরণ।
ভারত দোদেজা

150

রেসের শর্ত কী?

আপনি সন্ধ্যা at টায় একটি সিনেমায় যাওয়ার পরিকল্পনা করছেন। আপনি বিকেল চারটায় টিকিটের প্রাপ্যতা সম্পর্কে অনুসন্ধান করুন। প্রতিনিধি জানান যে তারা উপলব্ধ। আপনি শিথিল এবং শো এর 5 মিনিট আগে টিকিট উইন্ডোতে পৌঁছেছেন। আমি নিশ্চিত যে আপনি কী অনুমান করতে পারবেন: এটি একটি সম্পূর্ণ বাড়ি। এখানে সমস্যাটি চেক এবং ক্রিয়াটির মধ্যে সময়কালে ছিল। আপনি 4 এ অনুসন্ধান করেছিলেন এবং 5 তে অভিনয় করেছেন এর মধ্যে, অন্য কেউ টিকিট ধরেছে। এটি একটি রেসের শর্ত - বিশেষত জাতি শর্তগুলির "চেক-অফ-অ্যাক্ট" দৃশ্য।

আপনি তাদের সনাক্ত করতে পারেন?

ধর্মীয় কোড পর্যালোচনা, বহু-থ্রেড ইউনিট পরীক্ষা। কোনও শর্টকাট নেই। এটিতে খুব কম Eclipse প্লাগইন উত্থিত হয়েছে, তবে এখনও স্থিতিশীল কিছুই নেই।

আপনি কীভাবে তাদের পরিচালনা এবং প্রতিরোধ করবেন?

সবচেয়ে ভাল জিনিসটি পার্শ্ব-প্রতিক্রিয়া মুক্ত এবং স্টেটলেস ফাংশন তৈরি করা, যতটা সম্ভব অপরিবর্তনীয় ব্যবহার করা উচিত। তবে তা সবসময় সম্ভব হয় না। সুতরাং java.util.concurrent.atomic, একত্রে ডেটা স্ট্রাকচার, যথাযথ সিঙ্ক্রোনাইজেশন এবং অভিনেতা ভিত্তিক একত্রীকরণ ব্যবহার সাহায্য করবে।

সমঝোতার জন্য সেরা উত্স হ'ল জেসিআইপি। উপরের ব্যাখ্যায় আপনি আরও কিছু বিশদ এখানে পেতে পারেন ।


কোড পর্যালোচনা এবং ইউনিট পরীক্ষাগুলি আপনার কানের মধ্যে প্রবাহকে মডেলিং করার জন্য এবং ভাগ করা মেমরির কম ব্যবহার করার ক্ষেত্রে গৌণ are
একিউম্যানাস

2
আমি রেসের শর্তের বাস্তব বিশ্বের উদাহরণটির প্রশংসা করেছি
টম ও

11
উত্তর থাম্বস আপ মত । সমাধানটি হ'ল: আপনি 4-5-এর মধ্যে টিকিটগুলিকে মুটেক্সের সাথে লক করুন (পারস্পরিক ব্যতিক্রম, সি ++)। বাস্তব বিশ্বে একে টিকিট রিজার্ভেশন বলা হয় :)
ভোল্ট

1
আপনি জাভা-শুধুমাত্র বিট বাদ দিলে একটি উপযুক্ত উত্তর হবে (প্রশ্নটি জাভা সম্পর্কে নয়, বরং সাধারণভাবে রেসের অবস্থা)
কোরি গোল্ডবার্গ ২berg

না এটি কোনও রেসের শর্ত নয়। একটি "ব্যবসায়" দৃষ্টিকোণ থেকে আপনি সবেমাত্র দীর্ঘ অপেক্ষা করেছিলেন। স্পষ্টতই ব্যাকর্ডার কোনও সমাধান নয়। একটি স্ক্যাল্পার চেষ্টা করুন অন্যথায় কেবল বীমা হিসাবে টিকিটটি
কিনুন

65

রেসের শর্ত এবং ডেটা রেসের মধ্যে একটি গুরুত্বপূর্ণ প্রযুক্তিগত পার্থক্য রয়েছে। বেশিরভাগ উত্তরগুলি এই পদগুলি সমতুল্য বলে অনুমান করে বলে মনে হয়, তবে তা নয়।

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

একটি রেসের শর্তটি একটি অর্থপূর্ণ ত্রুটি। এটি একটি ত্রুটি যা সময় নির্ধারণের সময় বা ইভেন্টগুলির ক্রম ঘটে যা ভুল প্রোগ্রাম আচরণের দিকে পরিচালিত করে

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

এখন আমরা যে পরিভাষাটি পেরেক দিয়েছি, আসুন আসল প্রশ্নের উত্তর দেওয়ার চেষ্টা করি।

বর্ণের শর্তগুলি সিনমেটিক বাগগুলি দেওয়া, এগুলি সনাক্ত করার কোনও সাধারণ উপায় নেই। এটি কারণ একটি স্বয়ংক্রিয় ওরাকল থাকার কোনও উপায় নেই যা সাধারণ ক্ষেত্রে সঠিক বনাম ভুল প্রোগ্রাম আচরণের পার্থক্য করতে পারে। জাতি সনাক্তকরণ একটি অনস্বীকার্য সমস্যা।

অন্যদিকে, ডেটা রেসের একটি সুনির্দিষ্ট সংজ্ঞা রয়েছে যা অগত্যা সংশোধনের সাথে সম্পর্কিত নয় এবং তাই এটির দ্বারা এটি সনাক্ত করা যায়। ডেটা রেস ডিটেক্টরগুলির প্রচুর স্বাদ রয়েছে (স্ট্যাটিক / ডায়নামিক ডেটা রেস ডিটেকশন, লকসেট-ভিত্তিক ডেটা রেস সনাক্তকরণ, ঘটনার আগে ভিত্তিক ডেটা রেস সনাক্তকরণ, সংকর ডেটা রেস সনাক্তকরণ)। আর্ট ডায়নামিক ডেটা রেস ডিটেক্টরের একটি স্টেট হ'ল থ্রেডস্যানিটাইজার যা অনুশীলনে খুব ভালভাবে কাজ করে।

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


পার্থক্য জাতি অবস্থা বুঝতে গুরুত্বপূর্ণ। ধন্যবাদ!
ProgramCpp

37

একটি প্রকারান্তরে সংজ্ঞাযুক্ত সংজ্ঞাটি হয় " যখন দুটি থ্রেড একই সময়ে মেমরিতে একই স্থানে অ্যাক্সেস করে এবং কমপক্ষে প্রবেশের একটিতে লেখা হয় ।" পরিস্থিতিতে "পাঠক" থ্রেডটি কোন থ্রেডের উপর নির্ভর করে "রেসটি জিতবে" পুরানো মান বা নতুন মান পেতে পারে। এটি সবসময় কোনও ত্রুটি নয় fact আসলে, কিছু লোমশ লোয়ার নিম্ন-স্তরের অ্যালগরিদমগুলি উদ্দেশ্য হিসাবে এটি করে - তবে এটি সাধারণত এড়ানো উচিত। @ স্টিভ গুরির দেওয়া সমস্যাটি কখন হতে পারে তার একটি উত্তম উদাহরণ।


3
আপনি কী দয়া করে দৌড়ের পরিস্থিতি কার্যকর হতে পারে তার একটি উদাহরণ দিতে পারেন? গুগলিং সাহায্য করেনি।
অ্যালেক্স ভি।

3
@ অ্যালেক্স ভি। এই মুহুর্তে, আমি কী বলছিলাম সে সম্পর্কে আমার কোনও ধারণা নেই। আমি মনে করি এটি লক-ফ্রি প্রোগ্রামিংয়ের একটি উল্লেখ হতে পারে তবে এটি প্রতিদ্বন্দ্বী জাতিগত অবস্থার উপর নির্ভর করে তা বলা সত্যিই সঠিক নয়।
ক্রিস কনওয়ে

33

একটি রেসের শর্তটি এক ধরণের বাগ, এটি কেবলমাত্র নির্দিষ্ট অস্থায়ী অবস্থার সাথে ঘটে।

উদাহরণ: কল্পনা করুন আপনার দুটি এবং থ্রেড রয়েছে, এ এবং বি B.

থ্রেড এ:

if( object.a != 0 )
    object.avg = total / object.a

থ্রেড বি:

object.a = 0

থ্রেড এ যদি সেই অবজেক্টটি পরীক্ষা করার ঠিক পরে ডেকে আনে তবে এটি নাল নয়, বি করবে a = 0এবং থ্রেড এ যখন প্রসেসর অর্জন করবে তখন এটি "শূন্য দ্বারা বিভাজন" করবে।

এই বাগটি কেবল তখনই ঘটে যখন থ্রেড এ এর ​​স্টেটমেন্টের ঠিক পরে ডাকা হয়ে থাকে, এটি খুব বিরল, তবে এটি ঘটতে পারে।


21

রেস শর্ত শুধুমাত্র সফ্টওয়্যার এর সাথে সম্পর্কিত নয় তবে হার্ডওয়্যারের সাথেও সম্পর্কিত। আসলে এই শব্দটি প্রথমে হার্ডওয়্যার ইন্ডাস্ট্রির দ্বারা তৈরি হয়েছিল।

উইকিপিডিয়া অনুসারে :

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

লজিক সার্কিটের রেসের অবস্থা:

এখানে চিত্র বর্ণনা লিখুন

সফ্টওয়্যার শিল্পটি এই পদটি কোনও পরিবর্তন ছাড়াই নিয়েছিল, যা এটি বুঝতে কিছুটা কঠিন করে তোলে।

এটি সফ্টওয়্যার বিশ্বে মানচিত্র করার জন্য আপনাকে কিছু প্রতিস্থাপন করতে হবে:

  • "দুটি সংকেত" => "দুটি থ্রেড" / "দুটি প্রক্রিয়া"
  • "আউটপুটকে প্রভাবিত করুন" => "কিছু ভাগ করা রাষ্ট্রকে প্রভাবিত করুন"

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


20

রেসের শর্তটি সমবর্তী প্রোগ্রামিংয়ের এমন একটি পরিস্থিতি যেখানে দুটি সমবর্তী থ্রেড বা প্রক্রিয়া একটি সংস্থার জন্য প্রতিযোগিতা করে এবং ফলস্বরূপ চূড়ান্ত রাষ্ট্রটি প্রথমে কে এই সংস্থানটি পায় তার উপর নির্ভর করে।


কেবল উজ্জ্বল ব্যাখ্যা
gokareless

চূড়ান্ত অবস্থা কী?
রোমান আলেকজান্দ্রোভিচ

1
@ রোমানআলেক্সান্দ্রোভিচ প্রোগ্রামটির চূড়ান্ত অবস্থা। রাষ্ট্র যেমন ভেরিয়েবলের মান ইত্যাদির বিষয়ে উল্লেখ করে লেহানের চমৎকার উত্তর দেখুন। "উদাহরণস্বরূপ" রাষ্ট্র "x 'এবং' y 'এর চূড়ান্ত মানকে বোঝায়।
এএমটার্প

19

রেস শর্তগুলি বহু-থ্রেডযুক্ত অ্যাপ্লিকেশন বা মাল্টি-প্রক্রিয়া সিস্টেমগুলিতে ঘটে। একটি জাতির শর্ত, এটির প্রাথমিকতম, এমনটি যা এমন ধারণা তৈরি করে যে দুটি জিনিস একই থ্রেড বা প্রক্রিয়াতে নয় একটি নির্দিষ্ট ক্রমে ঘটবে, তা নিশ্চিত করার পদক্ষেপ না নিয়েই। এটি সাধারণত ঘটে যখন দুটি থ্রেড উভয়ই ক্লাসের সদস্য ভেরিয়েবলগুলি সেট করে পরীক্ষা করে বার্তা প্রেরণ করে। প্রায় সবসময়ই একটি দৌড়ের শর্ত থাকে যখন কোনও থ্রেড কোনও কাজ শেষ করতে অন্য থ্রেডকে সময় দেওয়ার জন্য স্লিপকে কল করে (যদি না কিছু ঘুমের ফাঁকে না থাকে তবে কিছু পরীক্ষার ব্যবস্থা রয়েছে)।

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

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

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


10

মাইক্রোসফ্ট জাতিগত পরিস্থিতি এবং অচলাবস্থার বিষয়ে সত্যই একটি বিস্তারিত নিবন্ধ প্রকাশ করেছে । এটি থেকে সংক্ষিপ্ত বিবরণটি শিরোনাম অনুচ্ছেদ হবে:

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


5

রেসের অবস্থা কী?

প্রক্রিয়াটি ক্রিয়াকলাপভাবে অন্যান্য ইভেন্টের ক্রম বা সময় নির্ভর করে।

উদাহরণস্বরূপ, প্রসেসর এ এবং প্রসেসর বি উভয়ের কার্যকর করার জন্য অভিন্ন সংস্থান দরকার

আপনি তাদের সনাক্ত করতে পারেন?

জাতিগুলির শর্তটি স্বয়ংক্রিয়ভাবে সনাক্ত করার জন্য সরঞ্জামগুলি রয়েছে:

কিভাবে আপনি তাদের হ্যান্ডেল করবেন?

রেস অবস্থা দ্বারা পরিচালিত করা যেতে পারে mutex বা Semaphores । তারা লক হিসাবে কাজ করে এমন একটি প্রক্রিয়া জাতির শর্ত রোধ করতে নির্দিষ্ট প্রয়োজনীয়তার উপর ভিত্তি করে একটি সংস্থান অর্জন করতে দেয়।

কীভাবে আপনি তাদের সংঘটন থেকে রোধ করবেন?

জাতিদের অবস্থা প্রতিরোধের বিভিন্ন উপায় রয়েছে যেমন সমালোচনামূলক বিভাগ এড়ানো

  1. তাদের সমালোচনামূলক অঞ্চলে একসাথে কোনও দুটি প্রক্রিয়া নেই। ( পারস্পরিক বাদে)
  2. গতি বা সিপিইউগুলির সংখ্যা সম্পর্কে কোনও অনুমান করা হয় না।
  3. এর প্রক্রিয়াজাত অঞ্চলের বাইরে কোনও প্রক্রিয়া চলছে না যা অন্যান্য প্রক্রিয়াগুলিকে অবরুদ্ধ করে।
  4. এর প্রক্রিয়াজাত অঞ্চলে প্রবেশের জন্য কোনও প্রক্রিয়া চিরকাল অপেক্ষা করতে হবে না। (একটি বি সংস্থানগুলির জন্য অপেক্ষা করে, বি সি সংস্থানগুলির জন্য অপেক্ষা করে, সি এ সংস্থানগুলির জন্য অপেক্ষা করে)

2

রেস শর্তটি একটি অনাকাঙ্ক্ষিত পরিস্থিতি যা ঘটে যখন কোনও ডিভাইস বা সিস্টেম একই সাথে দু'এর বেশি ক্রিয়াকলাপ চালানোর চেষ্টা করে তবে ডিভাইস বা সিস্টেমের প্রকৃতির কারণে অপারেশনগুলি অবশ্যই যথাযথ ক্রমে সম্পন্ন করতে হবে সঠিকভাবে সম্পন্ন

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


2

এখানে ধ্রুপদী ব্যাংক অ্যাকাউন্টের ভারসাম্যের উদাহরণ রয়েছে যা জাবাতে থ্রেডগুলি সহজেই জাতির শর্তগুলিতে কব্জি করতে নবাবিদের সহায়তা করবে:

public class BankAccount {

/**
 * @param args
 */
int accountNumber;
double accountBalance;

public synchronized boolean Deposit(double amount){
    double newAccountBalance=0;
    if(amount<=0){
        return false;
    }
    else {
        newAccountBalance = accountBalance+amount;
        accountBalance=newAccountBalance;
        return true;
    }

}
public synchronized boolean Withdraw(double amount){
    double newAccountBalance=0;
    if(amount>accountBalance){
        return false;
    }
    else{
        newAccountBalance = accountBalance-amount;
        accountBalance=newAccountBalance;
        return true;
    }
}

public static void main(String[] args) {
    // TODO Auto-generated method stub
    BankAccount b = new BankAccount();
    b.accountBalance=2000;
    System.out.println(b.Withdraw(3000));

}

1

আপনি "পারমাণবিক" ক্লাস ব্যবহার করেন তবে আপনি রেসের অবস্থা রোধ করতে পারেন। কারণটি হ'ল থ্রেডটি আলাদা অপারেশন পেতে এবং সেট না করে, উদাহরণটি নীচে:

AtomicInteger ai = new AtomicInteger(2);
ai.getAndAdd(5);

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


0

জাতি অবস্থা সম্পর্কে আরও ভাল বোঝার জন্য এই প্রাথমিক উদাহরণটি ব্যবহার করে দেখুন:

    public class ThreadRaceCondition {

    /**
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        Account myAccount = new Account(22222222);

        // Expected deposit: 250
        for (int i = 0; i < 50; i++) {
            Transaction t = new Transaction(myAccount,
                    Transaction.TransactionType.DEPOSIT, 5.00);
            t.start();
        }

        // Expected withdrawal: 50
        for (int i = 0; i < 50; i++) {
            Transaction t = new Transaction(myAccount,
                    Transaction.TransactionType.WITHDRAW, 1.00);
            t.start();

        }

        // Temporary sleep to ensure all threads are completed. Don't use in
        // realworld :-)
        Thread.sleep(1000);
        // Expected account balance is 200
        System.out.println("Final Account Balance: "
                + myAccount.getAccountBalance());

    }

}

class Transaction extends Thread {

    public static enum TransactionType {
        DEPOSIT(1), WITHDRAW(2);

        private int value;

        private TransactionType(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }
    };

    private TransactionType transactionType;
    private Account account;
    private double amount;

    /*
     * If transactionType == 1, deposit else if transactionType == 2 withdraw
     */
    public Transaction(Account account, TransactionType transactionType,
            double amount) {
        this.transactionType = transactionType;
        this.account = account;
        this.amount = amount;
    }

    public void run() {
        switch (this.transactionType) {
        case DEPOSIT:
            deposit();
            printBalance();
            break;
        case WITHDRAW:
            withdraw();
            printBalance();
            break;
        default:
            System.out.println("NOT A VALID TRANSACTION");
        }
        ;
    }

    public void deposit() {
        this.account.deposit(this.amount);
    }

    public void withdraw() {
        this.account.withdraw(amount);
    }

    public void printBalance() {
        System.out.println(Thread.currentThread().getName()
                + " : TransactionType: " + this.transactionType + ", Amount: "
                + this.amount);
        System.out.println("Account Balance: "
                + this.account.getAccountBalance());
    }
}

class Account {
    private int accountNumber;
    private double accountBalance;

    public int getAccountNumber() {
        return accountNumber;
    }

    public double getAccountBalance() {
        return accountBalance;
    }

    public Account(int accountNumber) {
        this.accountNumber = accountNumber;
    }

    // If this method is not synchronized, you will see race condition on
    // Remove syncronized keyword to see race condition
    public synchronized boolean deposit(double amount) {
        if (amount < 0) {
            return false;
        } else {
            accountBalance = accountBalance + amount;
            return true;
        }
    }

    // If this method is not synchronized, you will see race condition on
    // Remove syncronized keyword to see race condition
    public synchronized boolean withdraw(double amount) {
        if (amount > accountBalance) {
            return false;
        } else {
            accountBalance = accountBalance - amount;
            return true;
        }
    }
}

0

আপনি সর্বদা একটি দৌড় শর্ত বাতিল করতে চান না। যদি আপনার কাছে একটি পতাকা থাকে যা একাধিক থ্রেড দ্বারা পড়া এবং লেখা যায় এবং এই পতাকাটি একটি থ্রেড দ্বারা 'সম্পন্ন' সেট করা থাকে যাতে অন্য থ্রেডটি প্রক্রিয়াটি বন্ধ করে দেয় যখন পতাকাটি 'সম্পন্ন' সেট করা হয়, আপনি "জাতি" চান না শর্ত "অপসারণ করা। প্রকৃতপক্ষে, এটিকে একটি সৌম্য জাতি শর্ত হিসাবে উল্লেখ করা যেতে পারে।

তবে, জাতি শর্ত সনাক্তকরণের জন্য একটি সরঞ্জাম ব্যবহার করে, এটি একটি ক্ষতিকারক রেসের শর্ত হিসাবে চিহ্নিত করা হবে।

রেসের শর্ত সম্পর্কে আরও বিশদ এখানে, http://msdn.microsoft.com/en-us/magazine/cc546569.aspx


আপনার উত্তরটি কোন ভাষা ভিত্তিক?
মাইকএমবি

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

0

একটি ক্রিয়াকলাপ বিবেচনা করুন যা গণনাটি বাড়ানোর সাথে সাথে কাউন্টটি প্রদর্শন করতে হবে। উদাহরণস্বরূপ, কাউন্টারথ্রেড বৃদ্ধি পাওয়ার সাথে সাথে ডিসপ্লেথথ্রেডকে সম্প্রতি আপডেট হওয়া মানটি প্রদর্শন করা দরকার।

int i = 0;

আউটপুট

CounterThread -> i = 1  
DisplayThread -> i = 1  
CounterThread -> i = 2  
CounterThread -> i = 3  
CounterThread -> i = 4  
DisplayThread -> i = 4

এখানে কাউন্টারথ্রেড প্রায়শই লক পায় এবং ডিসপ্লেথ্রেড প্রদর্শিত হওয়ার আগে মান আপডেট করে । এখানে একটি রেসের শর্ত রয়েছে। সিঙ্ক্রোনাইজেশন ব্যবহার করে রেস শর্তটি সমাধান করা যেতে পারে


0

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

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