লক ঠিক কীভাবে কাজ করে?


526

আমি দেখতে পেলাম যে থ্রেডগুলি নিরাপদ নয় এমন বস্তুগুলি ব্যবহারের জন্য আমরা কোডটিকে এই জাতীয় একটি লক দিয়ে মোড়া করি:

private static readonly Object obj = new Object();

lock (obj)
{
    // thread unsafe code
}

সুতরাং যখন একাধিক থ্রেডগুলি একই কোড অ্যাক্সেস করে তখন কী ঘটে (আসুন ধরে নেওয়া যাক এটি একটি এএসপি.নেট ওয়েব অ্যাপ্লিকেশনে চলছে)। তারা কি সারিবদ্ধ? তা হলে তারা আর কতক্ষণ অপেক্ষা করবে?

লক ব্যবহারের কারণে পারফরম্যান্সের প্রভাব কী?


1
^ মৃত লিঙ্ক, দেখুন: jonskeet.uk/csharp/threads/index.html
ইভান পাভিসি

উত্তর:


447

lockবিবৃতি নিম্নলিখিত সি # 3.0 অনুবাদ হয়:

var temp = obj;

Monitor.Enter(temp);

try
{
    // body
}
finally
{
    Monitor.Exit(temp);
}

সি # 4.0 এ এটি পরিবর্তিত হয়েছে এবং এটি এখন নিম্নলিখিত হিসাবে উত্পন্ন হয়েছে:

bool lockWasTaken = false;
var temp = obj;
try
{
    Monitor.Enter(temp, ref lockWasTaken);
    // body
}
finally
{
    if (lockWasTaken)
    {
        Monitor.Exit(temp); 
    }
}

আপনি এখানে কি Monitor.Enterকরেন সে সম্পর্কে আরও তথ্য পেতে পারেন । এমএসডিএন উদ্ধৃত করতে:

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

Monitor.Enterপদ্ধতি অসীম অপেক্ষা করবে; এটা সময় শেষ হবে না


15
এমএসডিএন অনুসারে "লক (সি #) বা সিঙ্কলক (ভিজ্যুয়াল বেসিক) কীওয়ার্ডটি সাধারণত মনিটর শ্রেণীর সরাসরি ব্যবহারের চেয়ে বেশি পছন্দ করা হয়, উভয় কারণ লক বা সিঙ্কলকই আরও সংক্ষিপ্ত, এবং কারণ লক বা সিঙ্কলক নিশ্চিত করে যে অন্তর্নিহিত মনিটরটি মুক্তি পেয়েছে, এমনকি যদি সুরক্ষিত কোডটি একটি ব্যতিক্রম ছুঁড়ে। msdn.microsoft.com/en-us/library/ms173179.aspx
আইডেন স্ট্রাইডম

10
ভার টেম্পের = বিন্দুটি কী; লাইন। যেহেতু এটি কেবল একটি রেফারেন্স দিয়ে শুরু করা হচ্ছে, অন্যকে কী করতে ভাল হয়?
priehl

11
@prihl এটি objসম্পূর্ণ সিস্টেমকে অচলিত অবস্থায় না ফেলে ব্যবহারকারীকে পরিবর্তন করতে দেয়।
স্টিভেন

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

2
সঠিক। এটি- lockস্টেটমেন্ট এবং মনিটরের পুরো উদ্দেশ্য : যাতে আপনি অন্য থ্রেডটিকে চিন্তিত না করে কোনও থ্রেডে অপারেশন করতে পারেন।
ডিজ্জি এইচ। মফিন

285

এটি আপনার ভাবার চেয়ে সহজ।

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

lockশব্দ কল Enterব্লক শুরুতে এবং Exitব্লক শেষে। lockকীওয়ার্ডটি আসলে Monitorশেষ প্রান্তে ক্লাস পরিচালনা করে ।

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

private static readonly Object obj = new Object();

lock (obj)
{
    // critical section
}

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


9
আমাদের লক করার জন্য একটি ডামি অবজেক্ট তৈরি করা উচিত বা আমরা প্রসঙ্গে কোনও বিদ্যমান ভেরিয়েবলটি লক করতে পারি?
ব্যাটম্যাচি

9
@ ব্যাটমসি - একটি পৃথক প্রাইভেট ডামি অবজেক্টে লক করা আপনাকে গ্যারান্টি দেয় যে অন্য কেউ সেই অবজেক্টটিতে লক করছে না। আপনি যদি ডেটা লক করে থাকেন এবং সেই একই টুকরোগুলি যদি বাইরের কাছে দৃশ্যমান হয় তবে আপনি সেই গ্যারান্টিটি হারাবেন।
উমর আব্বাস

8
যদি একাধিক প্রক্রিয়া লকটি প্রকাশের অপেক্ষায় থাকে তবে কী ঘটে? অপেক্ষার প্রক্রিয়াগুলি কি সারিবদ্ধ রয়েছে যাতে তারা ফিফোর ক্রমে গুরুত্বপূর্ণ বিভাগটি লক করে রাখবে?
jstuardo

@ জাস্টুয়ার্ডো - সেগুলি সারিবদ্ধ, তবে অর্ডারটি ফিফো হওয়ার নিশ্চয়তা নেই। এই লিঙ্কটি দেখুন: albahari.com/threading/part2.aspx
উমর আব্বাস


47

না, তারা সারিবদ্ধ নয়, তারা ঘুমাচ্ছে

ফর্ম একটি লক বিবৃতি

lock (x) ... 

যেখানে x হল একটি রেফারেন্স-ধরণের অভিব্যক্তি, এটি হুবহু সমতুল্য

var temp = x;
System.Threading.Monitor.Enter(temp); 
try { ... } 
finally { System.Threading.Monitor.Exit(temp); }

আপনাকে কেবল এটি জানতে হবে যে তারা একে অপরের জন্য অপেক্ষা করছে এবং কেবলমাত্র একটি থ্রেড লক ব্লক প্রবেশ করবে, অন্যরা অপেক্ষা করবে ...

তাই এটি যথেষ্ট দ্রুত, আরো তাকান মনিটর .net সম্পূর্ণরূপে লেখা আছে বর্গ মনিটর সঙ্গে প্রতিফলক আরো বিস্তারিত জানার জন্য


6
নোট করুন যে lockবিবৃতিটির জন্য নির্গত কোডটি সি # 4 তে সামান্য পরিবর্তিত হয়েছে: ব্লগস.এমএসএনএন
বি

আর্সেনমক্র্ট, তাদের "ব্লকড" স্টেটের "কাতারে রাখা হয়নি?? আমার মনে হয় ঘুম এবং ব্লক রাজ্যের মধ্যে কিছু পার্থক্য আছে, তাই না?
মোহনাভেল

@ মোহনভেল বলতে কী বোঝাতে চাইছেন?
আর্সেন এমক্র্টচায়ান

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

1
আমি অনুমান করি প্রক্রিয়াটির পরিবর্তে আপনি থ্রেডটি বোঝাচ্ছেন ... যদি তা হয় তবে উত্তরটি না হলে, কোনটি প্রবেশ করবে তার কোনও গ্যারান্টি নেই ... আরও এখানে স্ট্যাকওভারফ্লো.com
আর্সেন এমক্রটিচিয়ান

29

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


11

পারফরম্যান্সের প্রভাবটি আপনি যেভাবে লক করবেন তার উপর নির্ভর করে। আপনি এখানে অপ্টিমাইজেশনের একটি ভাল তালিকা পেতে পারেন: http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-program/

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


1
তবে লো-লক কোডটি লেখার চেষ্টা করার ফলে আপনি ক্ষেত্রের বিশেষজ্ঞ হয়েও প্রায়শই সূক্ষ্ম, হার্ড-টু-ফাইন্ড এবং ফিক্স বাগ করতে পারেন। একটি লক ব্যবহার করা প্রায়শই দুটি খারাপের কম হয়। আপনার যতটা প্রয়োজন ঠিক ঠিক তেমন লক করা উচিত, আর নেই, কমও নয়!
লুক 13

1
@ লুক: কিছু ব্যবহারের নিদর্শন রয়েছে যেখানে লো-লক কোডটি খুব সহজ এবং সহজ হতে পারে [ do { oldValue = thing; newValue = updated(oldValue); } while (CompareExchange(ref thing, newValue, oldValue) != oldValue]। সবচেয়ে বড় বিপদটি হ'ল যদি প্রয়োজনীয় কৌশলগুলি হ'ল এই জাতীয় কৌশলগুলি কীভাবে পরিচালনা করা যায় তার বাইরে চলে যায়, এটি পরিচালনা করতে কোডটি মানিয়ে নেওয়া কঠিন হতে পারে be
সুপারক্যাট

লিঙ্কটি ভেঙে গেছে।
ক্যারেনরোজ

8

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


8

lockবিবৃতিতে কল অনুবাদ করা হয় Enterএবং Exitপদ্ধতি Monitor

lockবিবৃতি অনির্দিষ্টকালের জন্য অপেক্ষা লক বস্তু প্রকাশ করা হবে।


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