http://www.codeproject.com/Articles/28785/Thread-synchronization-Wait-and-Pulse-demystifiedMonitor.Pulse और प्रतीक्षा करें - अनपेक्षित व्यवहार
कतार:
तैयार कतार है कि एक विशेष लॉक के लिए इंतजार कर रहे हैं धागे का संग्रह है। मॉनिटर। वैट विधियां एक और कतार पेश करती हैं: प्रतीक्षा कतार। लॉक प्राप्त करने के इंतजार से पल्स के लिए प्रतीक्षा करने के लिए यह आवश्यक है । तैयार कतार की तरह, प्रतीक्षा कतार फीफो है।
अनुशंसित पैटर्न:
इन कतारों अनपेक्षित व्यवहार हो सकता है। जब एक पल्स होता है, प्रतीक्षा कतार का प्रमुख जारी किया जाता है और इसे कतार में जोड़ा जाता है। हालांकि, अगर तैयार कतार में अन्य धागे हैं, तो वे जारी किए गए थ्रेड से पहले लॉक प्राप्त करेंगे। यह समस्या है, क्योंकि लॉक प्राप्त करने वाला थ्रेड राज्य को बदल सकता है कि स्पंदित धागा निर्भर करता है। समाधान ताला बयान
* क्यू = कतार अंदर थोड़ी देर हालत का प्रयोग है।
इसके द्वारा, मैं समझता हूं कि जब मैं Pulse
पर कॉल करता हूं, तो यह समाप्त होने से पहले 2 चीजें करता है। सबसे पहले, यह प्रतीक्षा क्यू से तैयार क्यू तक एक थ्रेड हटा देता है। दूसरा, यह तैयार क्यू में लॉक प्राप्त करने में एक थ्रेड (बिना थ्रेड कौन जानता है) देता है; यह परवाह नहीं करता कि कौन लॉक प्राप्त करता है (थ्रेड जो प्रतीक्षा प्रश्न से आया था या किसी थ्रेड के लिए तैयार क्यू में था)।
अगर मैं उस के बारे में सही हूँ तो क्यों रहा है इस समस्या को ठीक करने के लिए मदद एक while
Monitor.Wait
से पहले (समस्या - नाड़ी समाप्त हो जाती है, भले ही धागा है कि इंतजार कर क्यू से आया ताला हासिल नहीं किया है)?
ए। मुझे बताएं कि क्या मैं Monitor.Pulse
के उद्देश्य के बारे में सही हूं।
बी। Pulse
आप हर बार जब आप का उत्पादन -
class Program
{
static Queue<int> queue = new Queue<int>();
static object someMonitor = new object();
static void Main(string[] args)
{
Thread Thread1 = new Thread(WorkAlltheTime);
Thread1.Name = "Thread1";
Thread Thread2 = new Thread(WorkAlltheTime);
Thread2.Name = "Thread2";
Thread Thread3 = new Thread(WorkOnce);
Thread3.Name = "Thread3";
Thread1.Start();
Thread2.Start();
Thread.Sleep(1000);
Thread3.Start();
Console.ReadLine();
}
static void WorkAlltheTime()
{
Console.WriteLine("Came in to Ready Q: " + Thread.CurrentThread.Name);
lock (someMonitor)
{
Console.WriteLine("Came out from Ready Q: " + Thread.CurrentThread.Name);
// Broken!
while (queue.Count == 0)
{
Console.WriteLine("Came in to Waiting Q: " + Thread.CurrentThread.Name);
Monitor.Wait(someMonitor);
Console.WriteLine("Came out from Waiting Q: " + Thread.CurrentThread.Name);
}
queue.Dequeue();
Console.WriteLine("Thread: "+Thread.CurrentThread.Name+" Pulled Out");
}
}
static void WorkOnce()
{
lock (someMonitor)
{
queue.Enqueue(1);
Monitor.Pulse(someMonitor);
}
}
}
धन्यवाद, मैंने आपके उदाहरण का पूरा कोड लिखा है और आपकी व्याख्या के साथ मैंने इसे 90 बार परीक्षण किया और अब मैं पूरी तरह से समझता हूं। धन्यवाद एजियन! –