ডেডলক এবং লাইভলকের মধ্যে পার্থক্য কী?


323

কেউ দয়া করে উদাহরণের সাথে ব্যাখ্যা করতে পারেন (কোডের) ডেডলক এবং লাইভলকের মধ্যে পার্থক্য কী ?


উত্তর:


398

Http://en.wikedia.org/wiki/Deadlock থেকে নেওয়া :

একযোগে কম্পিউটিংয়ে, একটি অচলাবস্থা এমন একটি অবস্থা যেখানে ক্রিয়াকলাপের একটি গ্রুপের প্রতিটি সদস্য কোনও অন্য সদস্যের একটি লক প্রকাশের অপেক্ষায় থাকে

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

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

লাইভলোক হ'ল কিছু অ্যালগরিদমের সাথে ঝুঁকি যা সনাক্ত করে এবং অচলাবস্থা থেকে পুনরুদ্ধার করে। যদি একাধিক প্রক্রিয়া পদক্ষেপ নেয়, অচল সনাক্তকরণ অ্যালগরিদম বারবার ট্রিগার করা যেতে পারে। কেবলমাত্র একটি প্রক্রিয়া (এলোমেলোভাবে বা অগ্রাধিকার অনুসারে নির্বাচিত) পদক্ষেপ গ্রহণ করে তা নিশ্চিত করে এড়ানো যায়।


8
আমি এটি ইতিমধ্যে খুঁজে পেয়েছি, তবে তাদের সেখানে উদাহরণ নেই যেমন আপনি দেখতে পাচ্ছেন, যাইহোক ধন্যবাদ
ম্যাকিন্ডোস 27:51

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

4
আপনি কি আমাকে একই উদাহরণ দিতে পারেন তবে অচলাবস্থার সাথে, অগ্রিম ধন্যবাদ
ম্যাকিন্ডোস

32
একটি অচলাবস্থার উদাহরণটি আরও সহজ ... দুটি প্রক্রিয়া A এবং B ধরে নেওয়া এবং প্রতিটি রিসোর্স আর 1 এবং রিসোর্স আর 2 চায়। ধরা যাক, এ আর 1 পেয়েছে (বা ইতিমধ্যে রয়েছে), এবং বি পেয়েছে (বা ইতিমধ্যে রয়েছে) আর 2। এখন প্রত্যেকে কোনও সময়সীমা ছাড়াই অপরটির সংস্থানটি পাওয়ার চেষ্টা করে। এটিকে ব্লক করা হয়েছে কারণ বি আর ২ রাখে, এবং বি ব্লক করা হয়েছে কারণ এ আর -১ টি ধারণ করে। প্রতিটি প্রক্রিয়া অবরুদ্ধ এবং এইভাবে অন্য সংস্থানগুলি চায় এমন রিসোর্সটি প্রকাশ করতে পারে না, ফলে অচলাবস্থা সৃষ্টি হয়।
mah

2
লেনদেনের মেমরির প্রসঙ্গে একটি দুর্দান্ত ভিডিও রয়েছে যা ডেডলক এবং
লাইভলক

78

Livelock

একটি থ্রেড প্রায়শই অন্য থ্রেডের ক্রিয়া প্রতিক্রিয়া হিসাবে কাজ করে। অন্য থ্রেডের ক্রিয়াটি যদি অন্য থ্রেডের ক্রিয়াটির প্রতিক্রিয়াও হয় তবে লাইভলকের ফলাফল হতে পারে।

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

লাইভলক এবং অচলাবস্থার মধ্যে প্রধান পার্থক্য হ'ল থ্রেডগুলি ব্লক করা হচ্ছে না, পরিবর্তে তারা একে অপরকে অবিরত সাড়া দেওয়ার চেষ্টা করবে।

এই চিত্রটিতে, উভয় চেনাশোনা (থ্রেড বা প্রক্রিয়া) বাম এবং ডানদিকে সরানোর মাধ্যমে অপরটিকে স্থান দেওয়ার চেষ্টা করবে। তবে তারা আর কোনও পদক্ষেপ নিতে পারে না।

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


Livelocks জন্য কোড উদাহরণ stackoverflow.com/questions/1036364/good-example-of-livelock
Yauhen Yakimovich

1
এই জিনিসটির একটি নাম আছে। একটি কুৎসিত শব্দ সম্ভবত, তবে এখনও: স্ক্লাম্পারডিংক : পি
জন রেড

64

এখানে সমস্ত বিষয়বস্তু এবং উদাহরণ থেকে

অপারেটিং সিস্টেমগুলি: অভ্যন্তরীণ এবং ডিজাইনের নীতিগুলি
উইলিয়াম স্ট্যালিংস
8º সংস্করণ

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

উদাহরণস্বরূপ, দুটি প্রক্রিয়া, P1 এবং P2 এবং দুটি সংস্থান, আর 1 এবং আর 2 বিবেচনা করুন। ধরুন যে প্রতিটি প্রক্রিয়াটির ক্রিয়াকলাপের অংশটি সম্পাদনের জন্য উভয় সংস্থার অ্যাক্সেসের প্রয়োজন। তারপরে নিম্নলিখিত পরিস্থিতিটি পাওয়া সম্ভব: ওএস আর 1 কে পি 2, এবং আর 2 কে পি 1 প্রদান করে। প্রতিটি প্রক্রিয়া দুটি সংস্থার একটির জন্য অপেক্ষা করছে। অন্য সংস্থান অর্জন না করে এবং উভয় সংস্থার প্রয়োজনে ফাংশন সম্পাদন না করা পর্যন্ত এটি ইতিমধ্যে মালিকানাধীন সংস্থানটি প্রকাশ করবে না। দুটি প্রক্রিয়া অচল অবস্থায় রয়েছে

লাইভলক : এমন একটি পরিস্থিতিতে যেখানে দুটি বা আরও বেশি প্রক্রিয়া কোনও কার্যকর কাজ না করেই অন্য প্রক্রিয়া (এস) এর পরিবর্তনের প্রতিক্রিয়া হিসাবে তাদের রাজ্যগুলিকে অবিচ্ছিন্নভাবে পরিবর্তন করে:

অনাহার : একটি পরিস্থিতি যেখানে একটি চলমান প্রক্রিয়া তফসিলকারী দ্বারা অনির্দিষ্টকালের জন্য উপেক্ষা করা হয়; যদিও এটি এগিয়ে যেতে সক্ষম, এটি কখনই চয়ন করা হয় না।

ধরুন যে তিনটি প্রক্রিয়া (পি 1, পি 2, পি 3) প্রতিটি রিসোর্স আরের পর্যায়ক্রমিক অ্যাক্সেসের প্রয়োজন। P1 এবং P3 উভয়ই সেই সংস্থার জন্য অপেক্ষা করে এমন পরিস্থিতিতে বিবেচনা করুন। যখন পি 1 তার সমালোচনামূলক বিভাগটি থেকে বেরিয়ে আসে, তখন পি 2 বা পি 3 কে আর এর অ্যাক্সেসের অনুমতি দেওয়া উচিত ume অনুমান করুন যে ওএস পি 3 এর অ্যাক্সেস দেয় এবং পি 3 এর সমালোচনামূলক বিভাগটি সম্পূর্ণ করার আগে পি 1 আবার অ্যাক্সেসের প্রয়োজন। পি 3 শেষ হওয়ার পরে ওএস যদি পি 1 এ অ্যাক্সেস দেয় এবং পরবর্তী সময়ে পি 1 এবং পি 3 এ অ্যাক্সেস দেয় তবে পিড 2 অনির্দিষ্টকালের জন্য রিসোর্সে অ্যাক্সেস অস্বীকার করতে পারে, যদিও কোনও অচলাবস্থার পরিস্থিতি নেই।

পরিশিষ্ট এ - কনসার্নির বিষয়সমূহ

অচল উদাহরণ

উভয় প্রক্রিয়া যদি বিবৃতিটি কার্যকর করার আগে উভয় প্রক্রিয়াতে তাদের পতাকাগুলি সত্য করে দেয় তবে প্রতিটি একে অপরটি তার সমালোচনামূলক বিভাগে প্রবেশ করেছে, যার ফলে অচলাবস্থার সৃষ্টি হয় causing

/* PROCESS 0 */
flag[0] = true;            // <- get lock 0
while (flag[1])            // <- is lock 1 free?
    /* do nothing */;      // <- no? so I wait 1 second, for example
                           // and test again.
                           // on more sophisticated setups we can ask
                           // to be woken when lock 1 is freed
/* critical section*/;     // <- do what we need (this will never happen)
flag[0] = false;           // <- releasing our lock

 /* PROCESS 1 */
flag[1] = true;
while (flag[0])
    /* do nothing */;
/* critical section*/;
flag[1] = false;

লাইভলক উদাহরণ

/* PROCESS 0 */
flag[0] = true;          // <- get lock 0
while (flag[1]){         
    flag[0] = false;     // <- instead of sleeping, we do useless work
                         //    needed by the lock mechanism
    /*delay */;          // <- wait for a second
    flag[0] = true;      // <- and restart useless work again.
}
/*critical section*/;    // <- do what we need (this will never happen)
flag[0] = false; 

/* PROCESS 1 */
flag[1] = true;
while (flag[0]) {
    flag[1] = false;
    /*delay */;
    flag[1] = true;
}
/* critical section*/;
flag[1] = false;

[...] ইভেন্টগুলির নিম্নলিখিত ক্রমটি বিবেচনা করুন:

  • P0 পতাকা সত্যে সেট করে [0]।
  • পি 1 পতাকাটিকে [1] সত্য হিসাবে সেট করে।
  • পি0 পতাকা চেক করে [1]।
  • পি 1 পতাকা চেক করে [0]।
  • পি 0 পতাকা [0] টি মিথ্যাতে সেট করে।
  • পি 1 পতাকাটি [1] কে মিথ্যা হিসাবে সেট করে।
  • P0 পতাকা সত্যে সেট করে [0]।
  • পি 1 পতাকাটিকে [1] সত্য হিসাবে সেট করে।

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

বই থেকে আর বিষয়বস্তু নয়।

আর স্পিনলকসের কী হবে?

স্পিনলক হ'ল ওএস লক ব্যবস্থার ব্যয় এড়াতে একটি কৌশল। সাধারণত আপনি করবেন:

try
{
   lock = beginLock();
   doSomething();
}
finally
{
   endLock();
}

এর beginLock()চেয়ে অনেক বেশি ব্যয় হলে একটি সমস্যা দেখা দিতে শুরু করে doSomething()। খুব উত্সাহিত শর্তে, beginLock1 সেকেন্ডের দাম পড়লে কী ঘটেছিল তা কল্পনা করুন , তবে doSomethingব্যয় হয় মাত্র 1 মিলিসেকেন্ড।

এই ক্ষেত্রে যদি আপনি 1 মিলিসেকেন্ড অপেক্ষা করেন তবে আপনি 1 সেকেন্ডের জন্য বাধা দেওয়া এড়াতে পারবেন।

এত beginLockখরচ হবে কেন ? লকটি নিখরচায় বিনামূল্যে ব্যয় না হলে ( https://stackoverflow.com/a/49712993/5397116 দেখুন ), তবে লকটি মুক্ত না হলে ওএস আপনার থ্রেডকে "হিমায়িত" করবে, আপনাকে জাগ্রত করার জন্য একটি ব্যবস্থা সেটআপ করুন যখন লকটি মুক্ত হয় এবং তারপরে আপনাকে ভবিষ্যতে আবার জাগিয়ে তুলবে।

এই সমস্ত কিছু লুপটি পরীক্ষা করে দেখার জন্য অনেক বেশি ব্যয়বহুল। যে কারণে কখনও কখনও একটি "স্পিনলক" করা ভাল।

উদাহরণ স্বরূপ:

void beginSpinLock(lock)
{
   if(lock) loopFor(1 milliseconds);
   else 
   {
     lock = true;
     return;
   }

   if(lock) loopFor(2 milliseconds);
   else 
   {
     lock = true;
     return;
   }

   // important is that the part above never 
   // cause the thread to sleep.
   // It is "burning" the time slice of this thread.
   // Hopefully for good.

   // some implementations fallback to OS lock mechanism
   // after a few tries
   if(lock) return beginLock(lock);
   else 
   {
     lock = true;
     return;
   }
}

যদি আপনার প্রয়োগটি সাবধান না হয় তবে আপনি লক মেকানিজমে সমস্ত সিপিইউ ব্যয় করে লাইভলকের উপর পড়তে পারেন।

আরও দেখুন:

https://preshing.com/20120226/roll-your-own-lightweight-mutex/
আমার স্পিন লক বাস্তবায়ন কি সঠিক এবং সর্বোত্তম?

সংক্ষিপ্তসার :

অচলাবস্থা : এমন পরিস্থিতি যেখানে কেউ অগ্রসর হয় না, কিছুই করে না (ঘুমানো, অপেক্ষারত ইত্যাদি ..)। সিপিইউ ব্যবহার কম হবে;

লাইভলক : এমন পরিস্থিতি যেখানে কেউ অগ্রসর হয় না, তবে সিপিইউ লক প্রক্রিয়াতে ব্যয় হয় আপনার গণনায় নয়;

অনাহার: এমন এক পরিস্থিতিতে যেখানে একজন প্রার্থী কখনই দৌড়ানোর সুযোগ পায় না; খাঁটি দুর্ভাগ্য দ্বারা বা এর কিছু সম্পত্তি দ্বারা (নিম্ন অগ্রাধিকার, উদাহরণস্বরূপ);

স্পিনলক : লকটি মুক্ত হওয়ার জন্য অপেক্ষা করা ব্যয়টি এড়ানোর কৌশল।


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

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

স্পিনলকগুলি যুক্ত করার জন্য আপনাকে ধন্যবাদ, আপনার মতে স্পিনলকস একটি কৌশল এবং আপনি এটিও ন্যায়সঙ্গত করেছেন এবং আমি বুঝতে পেরেছি। কিন্তু সেই অগ্রাধিকার বিপর্যয়জনিত সমস্যা সম্পর্কে কী যখন একটি প্রক্রিয়া পি 1 সমালোচনামূলক বিভাগে থাকে এবং অন্যান্য উচ্চ অগ্রাধিকার প্রক্রিয়া পি 2 নির্ধারিত প্রিমিটিং পি 1 পায় তখন এই ক্ষেত্রে সিপিইউ পি 2 এর সাথে থাকে এবং আমাদের সিঙ্ক্রোনাইজেশন প্রক্রিয়া পি 1 এর সাথে থাকে। একে স্পিনলক বলা হয় কারণ পি 1 প্রস্তুত অবস্থায় রয়েছে এবং পি 2 রান অবস্থায় রয়েছে। এখানে স্পিনলক একটি সমস্যা। আমি কি জিনিসগুলি ঠিকঠাক করছি? আমি সঠিকভাবে জটিলতা পেতে সক্ষম নই। দয়া করে সহায়তা করুন
বিনয় যাদব

আপনার কাছে আমার পরামর্শ হ'ল আপনার সমস্যাটিকে আরও স্পষ্টভাবে উল্লেখ করে আরেকটি প্রশ্ন তৈরি করা। এখন, আপনি যদি "ব্যবহারকারীর স্পেস" এ থাকেন এবং পি 1 একটি স্পিনলকের সাথে সুরক্ষিত একটি সমালোচনামূলক অধিবেশনের অভ্যন্তরে রয়েছে একটি অসীম লুপ এবং এর প্রিম্প্ট প্রয়োগ করে; তারপরে পি 2 এটিতে প্রবেশ করার চেষ্টা করবে, ব্যর্থ হবে এবং তার সমস্ত সময়-স্লাইস পুড়িয়ে ফেলবে। আপনি একটি লাইভলক তৈরি করেছেন (একটি সিপিইউ হবে 100%)। (স্পিনলকের সাথে একটি সিঙ্ক আইও রক্ষা করার জন্য একটি খারাপ ব্যবহার হবে You আপনি সহজেই এই উদাহরণটি ব্যবহার করতে পারেন) "কার্নেল স্পেস" এ সম্ভবত এই নোটটি আপনাকে সহায়তা করতে পারে: lxr.linux.no/linux+v3.6.6
ড্যানিয়েল ফ্রেডেরিকো লিন্স লিট

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

13

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

লাইভলক লাইভলক অবস্থা দেখা দিতে পারে যখন দুটি বা ততোধিক কাজ নির্ভর করে যখন কোনও বৃত্তাকার নির্ভরতা শর্ত সৃষ্টি করে এমন কিছু সংস্থান ব্যবহার করে যেখানে সেই কাজগুলি চিরকালের জন্য চলতে থাকে, এইভাবে নিম্ন স্তরের সমস্ত স্তরের কাজগুলি চলমান থেকে অবরুদ্ধ করে থাকে (এই নিম্ন অগ্রাধিকারের কাজগুলি অনাহার নামে পরিচিত)


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

8

সম্ভবত এই দুটি উদাহরণ আপনাকে অচলাবস্থা এবং লাইভলকের মধ্যে পার্থক্য তুলে ধরে:


অচলাবস্থার জন্য জাভা-উদাহরণ:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class DeadlockSample {

    private static final Lock lock1 = new ReentrantLock(true);
    private static final Lock lock2 = new ReentrantLock(true);

    public static void main(String[] args) {
        Thread threadA = new Thread(DeadlockSample::doA,"Thread A");
        Thread threadB = new Thread(DeadlockSample::doB,"Thread B");
        threadA.start();
        threadB.start();
    }

    public static void doA() {
        System.out.println(Thread.currentThread().getName() + " : waits for lock 1");
        lock1.lock();
        System.out.println(Thread.currentThread().getName() + " : holds lock 1");

        try {
            System.out.println(Thread.currentThread().getName() + " : waits for lock 2");
            lock2.lock();
            System.out.println(Thread.currentThread().getName() + " : holds lock 2");

            try {
                System.out.println(Thread.currentThread().getName() + " : critical section of doA()");
            } finally {
                lock2.unlock();
                System.out.println(Thread.currentThread().getName() + " : does not hold lock 2 any longer");
            }
        } finally {
            lock1.unlock();
            System.out.println(Thread.currentThread().getName() + " : does not hold lock 1 any longer");
        }
    }

    public static void doB() {
        System.out.println(Thread.currentThread().getName() + " : waits for lock 2");
        lock2.lock();
        System.out.println(Thread.currentThread().getName() + " : holds lock 2");

        try {
            System.out.println(Thread.currentThread().getName() + " : waits for lock 1");
            lock1.lock();
            System.out.println(Thread.currentThread().getName() + " : holds lock 1");

            try {
                System.out.println(Thread.currentThread().getName() + " : critical section of doB()");
            } finally {
                lock1.unlock();
                System.out.println(Thread.currentThread().getName() + " : does not hold lock 1 any longer");
            }
        } finally {
            lock2.unlock();
            System.out.println(Thread.currentThread().getName() + " : does not hold lock 2 any longer");
        }
    }
}

নমুনা আউটপুট:

Thread A : waits for lock 1
Thread B : waits for lock 2
Thread A : holds lock 1
Thread B : holds lock 2
Thread B : waits for lock 1
Thread A : waits for lock 2

লাইভলকের জাভা-উদাহরণ:


import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LivelockSample {

    private static final Lock lock1 = new ReentrantLock(true);
    private static final Lock lock2 = new ReentrantLock(true);

    public static void main(String[] args) {
        Thread threadA = new Thread(LivelockSample::doA, "Thread A");
        Thread threadB = new Thread(LivelockSample::doB, "Thread B");
        threadA.start();
        threadB.start();
    }

    public static void doA() {
        try {
            while (!lock1.tryLock()) {
                System.out.println(Thread.currentThread().getName() + " : waits for lock 1");
                Thread.sleep(100);
            }
            System.out.println(Thread.currentThread().getName() + " : holds lock 1");

            try {
                while (!lock2.tryLock()) {
                    System.out.println(Thread.currentThread().getName() + " : waits for lock 2");
                    Thread.sleep(100);
                }
                System.out.println(Thread.currentThread().getName() + " : holds lock 2");

                try {
                    System.out.println(Thread.currentThread().getName() + " : critical section of doA()");
                } finally {
                    lock2.unlock();
                    System.out.println(Thread.currentThread().getName() + " : does not hold lock 2 any longer");
                }
            } finally {
                lock1.unlock();
                System.out.println(Thread.currentThread().getName() + " : does not hold lock 1 any longer");
            }
        } catch (InterruptedException e) {
            // can be ignored here for this sample
        }
    }

    public static void doB() {
        try {
            while (!lock2.tryLock()) {
                System.out.println(Thread.currentThread().getName() + " : waits for lock 2");
                Thread.sleep(100);
            }
            System.out.println(Thread.currentThread().getName() + " : holds lock 2");

            try {
                while (!lock1.tryLock()) {
                    System.out.println(Thread.currentThread().getName() + " : waits for lock 1");
                    Thread.sleep(100);
                }
                System.out.println(Thread.currentThread().getName() + " : holds lock 1");

                try {
                    System.out.println(Thread.currentThread().getName() + " : critical section of doB()");
                } finally {
                    lock1.unlock();
                    System.out.println(Thread.currentThread().getName() + " : does not hold lock 1 any longer");
                }
            } finally {
                lock2.unlock();
                System.out.println(Thread.currentThread().getName() + " : does not hold lock 2 any longer");
            }
        } catch (InterruptedException e) {
            // can be ignored here for this sample
        }
    }
}

নমুনা আউটপুট:

Thread B : holds lock 2
Thread A : holds lock 1
Thread A : waits for lock 2
Thread B : waits for lock 1
Thread B : waits for lock 1
Thread A : waits for lock 2
Thread A : waits for lock 2
Thread B : waits for lock 1
Thread B : waits for lock 1
Thread A : waits for lock 2
Thread A : waits for lock 2
Thread B : waits for lock 1
...

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


কোডটি দুর্দান্ত। তবে লাইভ-লক উদাহরণটি ভাল নয়। কোনও মানকে কোনও থ্রেড ব্লক করা হয়েছে বা মান পরিবর্তনের পক্ষে ভোট দিচ্ছে তা ধারণাগতভাবে আলাদা নয়। লাইভ-লককে আরও ভালভাবে চিত্রিত করার একটি সহজ পরিবর্তন হ'ল থ্রেড এ এবং বি থ্রেড থাকা যখন তারা বুঝতে পারে যে তারা প্রয়োজনীয় দ্বিতীয় লকটি পাচ্ছে না। তারপরে তারা প্রতিটি এক সেকেন্ডের জন্য ঘুমায়, মূলত তারা যে তালাটি রেখেছিল তা পুনরুদ্ধার করে, তারপরে আরেক সেকেন্ডের জন্য ঘুমাবে এবং আবার অন্য লকটি অর্জন করার চেষ্টা করবে। সুতরাং প্রত্যেকের জন্য চক্র হবে: 1) অর্জন-খনি, 2) ঘুম, 3) অন্য অর্জন করার চেষ্টা করুন এবং ব্যর্থ, 4) রিলিজ-মাইন, 5) ঘুম, 6) পুনরাবৃত্তি করুন।
কগনিজান্টেপ

1
আপনি যে লাইভ-লকগুলি ভাবেন বলে মনে করেন তা আসলেই যথেষ্ট দীর্ঘ কিনা তা নিয়েই আমি সন্দেহ করি they যখন আপনি সর্বদা আপনার পরবর্তী লক বরাদ্দ করতে না পারলে আপনি যে সমস্ত লক রাখেন তা ছেড়ে দেন, অচলিত (এবং লাইভ-লক) শর্তটি "হোল্ড অ্যান্ড ওয়েট" অনুপস্থিত কারণ সেখানে আর অপেক্ষা নেই actually ( En.wikipedia.org/wiki/Deadlock )
mmirwaldt

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

0

আপনি থ্রেড এ এবং থ্রেড বি কল্পনা করুন যে তারা উভয় synchronisedএকই বস্তুতে রয়েছে এবং এই ব্লকের ভিতরে একটি বৈশ্বিক পরিবর্তনশীল রয়েছে যা তারা উভয়ই আপডেট করছে;

static boolean commonVar = false;
Object lock = new Object;

...

void threadAMethod(){
    ...
    while(commonVar == false){
         synchornized(lock){
              ...
              commonVar = true
         }
    }
}

void threadBMethod(){
    ...
    while(commonVar == true){
         synchornized(lock){
              ...
              commonVar = false
         }
    }
}

সুতরাং যখন থ্রেড 'এ প্রবেশ whileলুপ এবং লক ঝুলিতে, এটা আছে এটা করতে এবং সেট করতে হয়েছে কি commonVarকরতে true। তারপর থ্রেড বি, আসে ঢোকে whileলুপ এবং যেহেতু commonVarহয় trueএখন, এটা লক রাখা পাবে হয়। এটি তাই করে, synchronisedব্লকটি কার্যকর করে এবং এতে commonVarফিরে আসে false। এখন, থ্রেড একটি আবার নতুন CPU- র জানালা পায়, এটা ছিল প্রস্থান করার জন্য সম্পর্কে whileলুপ কিন্তু থ্রেড বি শুধু এটা ফিরে সেট করেছে false, তাই চক্র পুনরাবৃত্তি আবার। থ্রেডগুলি কিছু করে (যাতে এগুলি প্রচলিত অর্থে অবরুদ্ধ করা হয় না) তবে প্রায় কিছুই না।

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


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