เชตเซ‡เชฒ-เชซเซ‡เชก เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเซเชธ เช…เชฅเชตเชพ เชธเซเชชเชฐเซเชงเชพเชคเซเชฎเช• .NET เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎเชฟเช‚เช—

เชตเซ‡เชฒ-เชซเซ‡เชก เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเซเชธ เช…เชฅเชตเชพ เชธเซเชชเชฐเซเชงเชพเชคเซเชฎเช• .NET เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎเชฟเช‚เช—

เชšเชพเชฒเซ‹ เชœเซ‹เชˆเช เช•เซ‡ .Net เชฎเชพเช‚ เชธเชฎเชตเชฐเซเชคเซ€ เช…เชจเซ‡ เชธเชฎเชพเช‚เชคเชฐ เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎเชฟเช‚เช— เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชพเชฐเซเชฏ เช•เชฐเซ‡ เช›เซ‡, เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡ เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเซเชธ เชกเชพเช‡เชจเชฟเช‚เช— เชชเซเชฐเซ‹เชฌเซเชฒเซ‡เชฎเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡. เชฏเซ‹เชœเชจเชพ เช† เช›เซ‡, เชฅเซเชฐเซ‡เชกเซ‹/เชชเซเชฐเช•เซเชฐเชฟเชฏเชพเช“เชจเชพ เชธเชฟเช‚เช•เซเชฐเชจเชพเช‡เชเซ‡เชถเชจเชฅเซ€ เชฒเชˆเชจเซ‡ เช…เชญเชฟเชจเซ‡เชคเชพ เชฎเซ‹เชกเซ‡เชฒ เชธเซเชงเซ€ (เชจเซ€เชšเซ‡เชจเชพ เชญเชพเช—เซ‹เชฎเชพเช‚). เชฒเซ‡เช– เชชเซเชฐเชฅเชฎ เชชเชฐเชฟเชšเชฟเชค เชฎเชพเชŸเซ‡ เช…เชฅเชตเชพ เชคเชฎเชพเชฐเชพ เชœเซเชžเชพเชจเชจเซ‡ เชคเชพเชœเซเช‚ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เช‰เชชเชฏเซ‹เช—เซ€ เชฅเชˆ เชถเช•เซ‡ เช›เซ‡.

เชถเชพ เชฎเชพเชŸเซ‡ เชคเซ‡ เชฌเชฟเชฒเช•เซเชฒ เช•เชฐเชตเซเช‚? เชŸเซเชฐเชพเช‚เชเชฟเชธเซเชŸเชฐ เชคเซ‡เชฎเชจเชพ เชฒเช˜เซเชคเซเชคเชฎ เช•เชฆ เชธเซเชงเซ€ เชชเชนเซ‹เช‚เชšเซ‡ เช›เซ‡, เชฎเซ‚เชฐเชจเซ‹ เช•เชพเชฏเชฆเซ‹ เชชเซเชฐเช•เชพเชถเชจเซ€ เช—เชคเชฟเชจเซ€ เชฎเชฐเซเชฏเชพเชฆเชพ เชชเชฐ เช†เชงเชพเชฐ เชฐเชพเช–เซ‡ เช›เซ‡ เช…เชจเซ‡ เชคเซ‡เชฅเซ€ เชธเช‚เช–เซเชฏเชพเชฎเชพเช‚ เชตเชงเชพเชฐเซ‹ เชœเซ‹เชตเชพ เชฎเชณเซ‡ เช›เซ‡, เชตเชงเซ เชŸเซเชฐเชพเช‚เชเชฟเชธเซเชŸเชฐ เชฌเชจเชพเชตเซ€ เชถเช•เชพเชฏ เช›เซ‡. เชคเซ‡ เชœ เชธเชฎเชฏเซ‡, เชกเซ‡เชŸเชพเชจเซ€ เชฎเชพเชคเซเชฐเชพ เชตเชงเซ€ เชฐเชนเซ€ เช›เซ‡, เช…เชจเซ‡ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพเช“ เชธเชฟเชธเซเชŸเชฎเซเชธ เชคเชฐเชซเชฅเซ€ เชคเชพเชคเซเช•เชพเชฒเชฟเช• เชชเซเชฐเชคเชฟเชธเชพเชฆเชจเซ€ เช…เชชเซ‡เช•เซเชทเชพ เชฐเชพเช–เซ‡ เช›เซ‡. เช†เชตเซ€ เชธเซเชฅเชฟเชคเชฟเชฎเชพเช‚, "เชธเชพเชฎเชพเชจเซเชฏ" เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎเชฟเช‚เช—, เชœเซเชฏเชพเชฐเซ‡ เช†เชชเชฃเซ€ เชชเชพเชธเซ‡ เชเช• เชœ เชเช•เซเชเชฟเช•เซเชฏเซเชŸเซ€เช‚เช— เชฅเซเชฐเซ‡เชก เชนเซ‹เชฏ เช›เซ‡, เชคเซ‡ เชนเชตเซ‡ เช…เชธเชฐเช•เชพเชฐเช• เชจเชฅเซ€. เชคเชฎเชพเชฐเซ‡ เช•เซ‹เชˆเช• เชฐเซ€เชคเซ‡ เชเช• เชธเชพเชฅเซ‡ เช…เชฅเชตเชพ เชธเชนเชตเชฐเซเชคเซ€ เช…เชฎเชฒเชจเซ€ เชธเชฎเชธเซเชฏเชพเชจเซ‡ เชนเชฒ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡. เชคเชฆเซเชชเชฐเชพเช‚เชค, เช† เชธเชฎเชธเซเชฏเชพ เชตเชฟเชตเชฟเชง เชธเซเชคเชฐเซ‡ เช…เชธเซเชคเชฟเชคเซเชตเชฎเชพเช‚ เช›เซ‡: เชฅเซเชฐเซ‡เชกเซ‹เชจเชพ เชธเซเชคเชฐเซ‡, เชชเซเชฐเช•เซเชฐเชฟเชฏเชพเช“เชจเชพ เชธเซเชคเชฐเซ‡, เชจเซ‡เชŸเชตเชฐเซเช•เชฎเชพเช‚ เชฎเชถเซ€เชจเซ‹เชจเชพ เชธเซเชคเชฐเซ‡ (เชตเชฟเชคเชฐเชฟเชค เชธเชฟเชธเซเชŸเชฎเซ‹). เช†เชตเซ€ เชธเชฎเชธเซเชฏเชพเช“เชจเซ‡ เชเชกเชชเชฅเซ€ เช…เชจเซ‡ เช…เชธเชฐเช•เชพเชฐเช• เชฐเซ€เชคเซ‡ เช‰เช•เซ‡เชฒเชตเชพ เชฎเชพเชŸเซ‡ .NET เชชเชพเชธเซ‡ เช‰เชšเซเชš-เช—เซเชฃเชตเชคเซเชคเชพเชตเชพเชณเซ€, เชธเชฎเชฏ-เชšเช•เชพเชธเชพเชฏเซ‡เชฒ เชคเช•เชจเซ€เช•เซ‹ เช›เซ‡.

เช‰เชฆเซเชฆเซ‡เชถ

เชเชกเซเช—เชฐ เชกเชฟเชœเช•เซเชธเซเชŸเซเชฐเชพเช 1965เชจเซ€ เชถเชฐเซ‚เช†เชคเชฎเชพเช‚ เชœ เชคเซ‡เชฎเชจเชพ เชตเชฟเชฆเซเชฏเชพเชฐเซเชฅเซ€เช“ เชธเชฎเช•เซเชท เช† เชธเชฎเชธเซเชฏเชพ เชŠเชญเซ€ เช•เชฐเซ€ เชนเชคเซ€. เชธเซเชฅเชพเชชเชฟเชค เชซเซ‹เชฐเซเชฎเซเชฏเซเชฒเซ‡เชถเชจ เชจเซ€เชšเซ‡ เชฎเซเชœเชฌ เช›เซ‡. เชซเชฟเชฒเชธเซ‚เชซเซ‹เชจเซ€ เชšเซ‹เช•เซเช•เชธ (เชธเชพเชฎเชพเชจเซเชฏ เชฐเซ€เชคเซ‡ เชชเชพเช‚เชš) เชธเช‚เช–เซเชฏเชพ เช…เชจเซ‡ เช•เชพเช‚เชŸเซ‹เชจเซ€ เชธเชฎเชพเชจ เชธเช‚เช–เซเชฏเชพ เช›เซ‡. เชคเซ‡เช“ เชฐเชพเช‰เชจเซเชก เชŸเซ‡เชฌเชฒ เชชเชฐ เชฌเซ‡เชธเซ‡ เช›เซ‡, เชคเซ‡เชฎเชจเซ€ เชตเชšเซเชšเซ‡ เช•เชพเช‚เชŸเซ‹. เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเซ‹ เชคเซ‡เชฎเชจเชพ เช…เชจเช‚เชค เช–เซ‹เชฐเชพเช•เชจเซ€ เชชเซเชฒเซ‡เชŸเชฎเชพเช‚เชฅเซ€ เช–เชพเชˆ เชถเช•เซ‡ เช›เซ‡, เชตเชฟเชšเชพเชฐเซ€ เชถเช•เซ‡ เช›เซ‡ เช…เชฅเชตเชพ เชฐเชพเชน เชœเซ‹เชˆ เชถเช•เซ‡ เช›เซ‡. เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเชจเซ‡ เช–เชพเชตเชพ เชฎเชพเชŸเซ‡, เชคเชฎเชพเชฐเซ‡ เชฌเซ‡ เช•เชพเช‚เชŸเซ‹ เชฒเซ‡เชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡ (เช›เซ‡เชฒเซเชฒเซ‹ เชเช• เช•เชพเช‚เชŸเซ‹ เชชเซเชฐเชฅเชฎ เชธเชพเชฅเซ‡ เชตเชนเซ‡เช‚เชšเซ‡ เช›เซ‡). เช•เชพเช‚เชŸเซ‹ เช‰เชชเชพเชกเชตเซ‹ เช…เชจเซ‡ เชจเซ€เชšเซ‡ เชฎเซ‚เช•เชตเซ‹ เช เชฌเซ‡ เช…เชฒเช—-เช…เชฒเช— เช•เซเชฐเชฟเชฏเชพเช“ เช›เซ‡. เชฌเชงเชพ เชซเชฟเชฒเชธเซ‚เชซเซ‹ เชฎเซŒเชจ เช›เซ‡. เช•เชพเชฐเซเชฏ เชเชตเซเช‚ เช…เชฒเซเช—เซ‹เชฐเชฟเชงเชฎ เชถเซ‹เชงเชตเชพเชจเซเช‚ เช›เซ‡ เช•เซ‡ เชคเซ‡ เชฌเชงเชพ 54 เชตเชฐเซเชท เชชเช›เซ€ เชชเชฃ เชตเชฟเชšเชพเชฐเซ‡ เช…เชจเซ‡ เชธเช‚เชชเซ‚เชฐเซเชฃ เชนเชถเซ‡.

เชชเซเชฐเชฅเชฎ, เชšเชพเชฒเซ‹ เชตเชนเซ‡เช‚เชšเชพเชฏเซ‡เชฒ เชœเช—เซเชฏเชพเชจเชพ เช‰เชชเชฏเซ‹เช— เชฆเซเชตเชพเชฐเชพ เช† เชธเชฎเชธเซเชฏเชพเชจเซ‡ เชนเชฒ เช•เชฐเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซ€เช. เช•เชพเช‚เชŸเชพ เชธเชพเชฎเชพเชจเซเชฏ เชŸเซ‡เชฌเชฒ เชชเชฐ เชชเชกเซ‡เชฒเชพ เชนเซ‹เชฏ เช›เซ‡ เช…เชจเซ‡ เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเซ‹ เชœเซเชฏเชพเชฐเซ‡ เชนเซ‹เชฏ เชคเซเชฏเชพเชฐเซ‡ เชคเซ‡เชจเซ‡ เชฒเชˆ เชœเชพเชฏ เช›เซ‡ เช…เชจเซ‡ เชชเชพเช›เซเช‚ เชฎเซ‚เช•เซ€ เชฆเซ‡ เช›เซ‡. เช…เชนเซ€เช‚ เชธเชฟเช‚เช•เซเชฐเชจเชพเช‡เชเซ‡เชถเชจ เชธเชพเชฅเซ‡ เชธเชฎเชธเซเชฏเชพเช“ เช›เซ‡, เชšเซ‹เช•เซเช•เชธ เช•เซเชฏเชพเชฐเซ‡ เชธเซเชฐเชฌเซ‡เชŸเซเชธ เชฒเซ‡เชตเชพ? เช•เชพเช‚เชŸเซ‹ เชจ เชนเซ‹เชฏ เชคเซ‹ เชถเซเช‚? เชตเช—เซ‡เชฐเซ‡. เชชเชฐเช‚เชคเซ เชชเชนเซ‡เชฒเชพ, เชšเชพเชฒเซ‹ เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเซ‹ เชถเชฐเซ‚ เช•เชฐเซ€เช.

เชฅเซเชฐเซ‡เชกเซ‹ เชถเชฐเซ‚ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡, เช…เชฎเซ‡ เชฅเซเชฐเซ‡เชก เชชเซ‚เชฒเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เช เช›เซ€เช Task.Run เชชเชฆเซเชงเชคเชฟ:

var cancelTokenSource = new CancellationTokenSource();
Action<int> create = (i) => RunPhilosopher(i, cancelTokenSource.Token);
for (int i = 0; i < philosophersAmount; i++) 
{
    int icopy = i;
    // ะŸะพะผะตัั‚ะธั‚ัŒ ะทะฐะดะฐั‡ัƒ ะฒ ะพั‡ะตั€ะตะดัŒ ะฟัƒะปะฐ ะฟะพั‚ะพะบะพะฒ. ะœะตั‚ะพะด RunDeadlock ะฝะต ะทะฐะฟัƒัะบะฐะตั‚ัŒัั 
    // ัั€ะฐะทัƒ, ะฐ ะถะดะตั‚ ัะฒะพะตะณะพ ะฟะพั‚ะพะบะฐ. ะัะธะฝั…ั€ะพะฝะฝั‹ะน ะทะฐะฟัƒัะบ.
    philosophers[i] = Task.Run(() => create(icopy), cancelTokenSource.Token);
}

เชฅเซเชฐเซ‡เชก เชชเซ‚เชฒ เชฅเซเชฐเซ‡เชก เชฌเชจเชพเชตเชตเชพ เช…เชจเซ‡ เช•เชพเชขเซ€ เชจเชพเช–เชตเชพเชจเซ‡ เช‘เชชเซเชŸเชฟเชฎเชพเช‡เช เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชฐเชšเชพเชฏเซ‡เชฒ เช›เซ‡. เช† เชชเซ‚เชฒเชฎเชพเช‚ เช•เชพเชฐเซเชฏเซ‹เชจเซ€ เช•เชคเชพเชฐ เช›เซ‡ เช…เชจเซ‡ CLR เช† เช•เชพเชฐเซเชฏเซ‹เชจเซ€ เชธเช‚เช–เซเชฏเชพเชจเชพ เช†เชงเชพเชฐเซ‡ เชฅเซเชฐเซ‡เชกเซ‹ เชฌเชจเชพเชตเซ‡ เช›เซ‡ เช…เชฅเชตเชพ เชฆเซ‚เชฐ เช•เชฐเซ‡ เช›เซ‡. เชฌเชงเชพ AppDomains เชฎเชพเชŸเซ‡ เชเช• เชชเซ‚เชฒ. เช† เชชเซ‚เชฒ เชฒเช—เชญเช— เชนเช‚เชฎเซ‡เชถเชพ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเซ‹ เชœเซ‹เชˆเช, เช•เชพเชฐเชฃ เช•เซ‡. เชฅเซเชฐเซ‡เชกเซ‹, เชคเซ‡เชฎเชจเซ€ เช•เชคเชพเชฐเซ‹ เชตเช—เซ‡เชฐเซ‡ เชฌเชจเชพเชตเชตเชพ, เช•เชพเชขเซ€ เชจเชพเช–เชตเชพเชฎเชพเช‚ เชชเชฐเซ‡เชถเชพเชจ เชฅเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชจเชฅเซ€. เชคเซ‡ เชชเซ‚เชฒ เชตเชฟเชจเชพ เชถเช•เซเชฏ เช›เซ‡, เชชเชฐเช‚เชคเซ เชชเช›เซ€ เชคเชฎเชพเชฐเซ‡ เชคเซ‡เชจเซ‹ เชธเซ€เชงเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเซ‹ เชชเชกเชถเซ‡ Thread, เช† เชเชตเชพ เช•เชฟเชธเซเชธเชพเช“ เชฎเชพเชŸเซ‡ เช‰เชชเชฏเซ‹เช—เซ€ เช›เซ‡ เชœเซเชฏเชพเชฐเซ‡ เชคเชฎเชพเชฐเซ‡ เชฅเซเชฐเซ‡เชกเชจเซ€ เชชเซเชฐเชพเชฅเชฎเชฟเช•เชคเชพ เชฌเชฆเชฒเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชนเซ‹เชฏ, เชœเซเชฏเชพเชฐเซ‡ เช…เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ เชฒเชพเช‚เชฌเซ€ เช•เชพเชฎเช—เซ€เชฐเซ€ เชนเซ‹เชฏ, เชซเซ‹เชฐเช—เซเชฐเชพเช‰เชจเซเชก เชฅเซเชฐเซ‡เชก เชตเช—เซ‡เชฐเซ‡ เชฎเชพเชŸเซ‡.

เชฌเซ€เชœเชพ เชถเชฌเซเชฆเซ‹ เชฎเชพเช‚, System.Threading.Tasks.Task เชตเชฐเซเช— เชธเชฎเชพเชจ เช›เซ‡ Thread, เชชเชฐเช‚เชคเซ เชคเชฎเชพเชฎ เชชเซเชฐเช•เชพเชฐเชจเซ€ เชธเช—เชตเชกเชคเชพเช“ เชธเชพเชฅเซ‡: เช…เชจเซเชฏ เช•เชพเชฐเซเชฏเซ‹เชจเชพ เชฌเซเชฒเซ‹เช• เชชเช›เซ€ เช•เชพเชฐเซเชฏเชจเซ‡ เชšเชฒเชพเชตเชตเชพเชจเซ€ เช•เซเชทเชฎเชคเชพ, เชคเซ‡เชฎเชจเซ‡ เช•เชพเชฐเซเชฏเซ‹เชฎเชพเช‚เชฅเซ€ เชชเชฐเชค เช•เชฐเชตเชพ, เชคเซ‡เชฎเชจเซ‡ เช…เชจเซเช•เซ‚เชณ เชฐเซ€เชคเซ‡ เชตเชฟเช•เซเชทเซ‡เชชเชฟเชค เช•เชฐเชตเชพ เช…เชจเซ‡ เชตเชงเซ. เชตเช—เซ‡เชฐเซ‡. เช…เชธเชฟเช‚เช•/เชชเซเชฐเชคเซ€เช•เซเชทเชพ เชฌเชพเช‚เชงเช•เชพเชฎเซ‹เชจเซ‡ เชŸเซ‡เช•เซ‹ เช†เชชเชตเชพ เชฎเชพเชŸเซ‡ เชคเซ‡เชฎเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡ (เชŸเชพเชธเซเช•-เช†เชงเชพเชฐเชฟเชค เช…เชธเชฟเช‚เช•เซเชฐเซ‹เชจเชธ เชชเซ‡เชŸเชฐเซเชจ, IO เช“เชชเชฐเซ‡เชถเชจเซเชธเชจเซ€ เชฐเชพเชน เชœเซ‹เชตเชพ เชฎเชพเชŸเซ‡ เชธเชฟเชจเซเชŸเซ‡เช•เซเชŸเชฟเช• เชธเซเช—เชฐ). เช…เชฎเซ‡ เช† เชตเชฟเชถเซ‡ เชชเช›เซ€เชฅเซ€ เชตเชพเชค เช•เชฐเซ€เชถเซเช‚.

CancelationTokenSource เช…เชนเซ€เช‚ เชคเซ‡ เชœเชฐเซ‚เชฐเซ€ เช›เซ‡ เชœเซ‡เชฅเซ€ เชฅเซเชฐเซ‡เชก เช•เซ‰เชฒเชฟเช‚เช— เชฅเซเชฐเซ‡เชกเชจเชพ เชธเช‚เช•เซ‡เชค เชชเชฐ เชชเซ‹เชคเชพเชจเซ‡ เชธเชฎเชพเชชเซเชค เช•เชฐเซ€ เชถเช•เซ‡.

เชธเชฎเชจเซเชตเชฏเชจ เชธเชฎเชธเซเชฏเชพเช“

เช…เชตเชฐเซ‹เชงเชฟเชค เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเซเชธ

เช เซ€เช• เช›เซ‡, เช†เชชเชฃเซ‡ เชœเชพเชฃเซ€เช เช›เซ€เช เช•เซ‡ เชฅเซเชฐเซ‡เชกเซ‹ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชฌเชจเชพเชตเชตเซ‹, เชšเชพเชฒเซ‹ เชฒเช‚เชš เช•เชฐเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซ€เช:

// ะšั‚ะพ ะบะฐะบะธะต ะฒะธะปะบะธ ะฒะทัะป. ะš ะฟั€ะธะผะตั€ัƒ: 1 1 3 3 - 1ะน ะธ 3ะน ะฒะทัะปะธ ะฟะตั€ะฒั‹ะต ะดะฒะต ะฟะฐั€ั‹.
private int[] forks = Enumerable.Repeat(0, philosophersAmount).ToArray();

// ะขะพ ะถะต, ั‡ั‚ะพ RunPhilosopher()
private void RunDeadlock(int i, CancellationToken token) 
{
    // ะ–ะดะฐั‚ัŒ ะฒะธะปะบัƒ, ะฒะทัั‚ัŒ ะตั‘. ะญะบะฒะธะฒะฐะปะตะฝั‚ะฝะพ: 
    // while(true) 
    //     if forks[fork] == 0 
    //          forks[fork] = i+1
    //          break
    //     Thread.Sleep() ะธะปะธ Yield() ะธะปะธ SpinWait()
    void TakeFork(int fork) =>
        SpinWait.SpinUntil(() => 
            Interlocked.CompareExchange(ref forks[fork], i+1, 0) == 0);

    // ะ”ะปั ะฟั€ะพัั‚ะพั‚ั‹, ะฝะพ ะผะพะถะฝะพ ั Interlocked.Exchange:
    void PutFork(int fork) => forks[fork] = 0;

    while (true)
    {
        TakeFork(Left(i));
        TakeFork(Right(i));
        eatenFood[i] = (eatenFood[i] + 1) % (int.MaxValue - 1);
        PutFork(Left(i));
        PutFork(Right(i));
        Think(i);

        // ะ—ะฐะฒะตั€ัˆะธั‚ัŒ ั€ะฐะฑะพั‚ัƒ ะฟะพ-ั…ะพั€ะพัˆะตะผัƒ.
        token.ThrowIfCancellationRequested();
    }
}

เช…เชนเซ€เช‚ เช†เชชเชฃเซ‡ เชชเชนเซ‡เชฒเชพ เชกเชพเชฌเซ‹ เช•เชพเช‚เชŸเซ‹ เชฒเซ‡เชตเชพเชจเซ‹ เชชเซเชฐเชฏเชคเซเชจ เช•เชฐเซ€เช เช›เซ€เช, เช…เชจเซ‡ เชชเช›เซ€ เชœเชฎเชฃเซ‹ เช•เชพเช‚เชŸเซ‹, เช…เชจเซ‡ เชœเซ‹ เชคเซ‡ เช•เชพเชฎ เช•เชฐเซ‡ เช›เซ‡, เชคเซ‹ เชชเช›เซ€ เช†เชชเชฃเซ‡ เช–เชพเชˆเช เช›เซ€เช เช…เชจเซ‡ เชคเซ‡เชจเซ‡ เชชเชพเช›เซเช‚ เชฎเซ‚เช•เซ€เช เช›เซ€เช. เชเช• เช•เชพเช‚เชŸเซ‹ เชฒเซ‡เชตเซ‹ เช เชชเชฐเชฎเชพเชฃเซ เช›เซ‡, เชเชŸเชฒเซ‡ เช•เซ‡. เชฌเซ‡ เชฅเซเชฐเซ‡เชกเซ‹ เชเช• เชœ เชธเชฎเชฏเซ‡ เชเช• เชฒเชˆ เชถเช•เชคเชพ เชจเชฅเซ€ (เช–เซ‹เชŸเซ‹: เชชเซเชฐเชฅเชฎ เชตเชพเช‚เชšเซ‡ เช›เซ‡ เช•เซ‡ เช•เชพเช‚เชŸเซ‹ เชฎเชซเชค เช›เซ‡, เชฌเซ€เชœเซ‹ - เชชเชฃ, เชชเซเชฐเชฅเชฎ เชฒเซ‡ เช›เซ‡, เชฌเซ€เชœเซ‹ เชฒเซ‡ เช›เซ‡). เช† เชฎเชพเชŸเซ‡ Interlocked.CompareExchange, เชœเซ‡ เชชเซเชฐเซ‹เชธเซ‡เชธเชฐ เชธเซ‚เชšเชจเชพ เชธเชพเชฅเซ‡ เช…เชฎเชฒเชฎเชพเช‚ เชฎเซ‚เช•เชตเซเช‚ เช†เชตเชถเซเชฏเช• เช›เซ‡ (TSL, XCHG), เชœเซ‡ เช…เชฃเซ เช…เชจเซเช•เซเชฐเชฎเชฟเช• เชตเชพเช‚เชšเชจ เช…เชจเซ‡ เชฒเซ‡เช–เชจ เชฎเชพเชŸเซ‡ เชฎเซ‡เชฎเชฐเซ€เชจเชพ เชŸเซเช•เชกเชพเชจเซ‡ เชคเชพเชณเซเช‚ เชฎเชพเชฐเซ‡ เช›เซ‡. เช…เชจเซ‡ SpinWait เช เชฌเชพเช‚เชงเช•เชพเชฎเชจเซ€ เชธเชฎเช•เช•เซเชท เช›เซ‡ while(true) เชฎเชพเชคเซเชฐ เชฅเซ‹เชกเชพ "เชœเชพเชฆเซ" เชธเชพเชฅเซ‡ - เชฅเซเชฐเซ‡เชก เชชเซเชฐเซ‹เชธเซ‡เชธเชฐ เชฒเซ‡ เช›เซ‡ (Thread.SpinWait), เชชเชฐเช‚เชคเซ เช•เซ‡เชŸเชฒเซ€เช•เชตเชพเชฐ เช…เชจเซเชฏ เชฅเซเชฐเซ‡เชก เชชเชฐ เชจเชฟเชฏเช‚เชคเซเชฐเชฃ เชธเซเชฅเชพเชจเชพเช‚เชคเชฐเชฟเชค เช•เชฐเซ‡ เช›เซ‡ (Thread.Yeild) เช…เชฅเชตเชพ เชŠเช‚เช˜เซ€ เชœเชพเชฏ เช›เซ‡ (Thread.Sleep).

เชชเชฐเช‚เชคเซ เช† เช‰เช•เซ‡เชฒ เช•เชพเชฎ เช•เชฐเชคเซเช‚ เชจเชฅเซ€, เช•เชพเชฐเชฃ เช•เซ‡ เชตเชนเซ‡เชคเซ‹ เชŸเซ‚เช‚เช• เชธเชฎเชฏเชฎเชพเช‚ (เชฎเชพเชฐเชพ เชฎเชพเชŸเซ‡ เชเช• เชธเซ‡เช•เชจเซเชกเชฎเชพเช‚) เช…เชตเชฐเซ‹เชงเชฟเชค เชฅเชˆ เชœเชพเชฏ เช›เซ‡: เชฌเชงเชพ เชซเชฟเชฒเชธเซ‚เชซเซ‹ เชคเซ‡เชฎเชจเซ‹ เชกเชพเชฌเซ‹ เช•เชพเช‚เชŸเซ‹ เชฒเซ‡ เช›เซ‡, เชชเชฐเช‚เชคเซ เชœเชฎเชฃเซ‹ เช•เชพเช‚เชŸเซ‹ เชจเชนเซ€เช‚. เชซเซ‹เชฐเซเช•เซเชธ เชเชฐเซ‡ เชชเช›เซ€ เชฎเซ‚เชฒเซเชฏเซ‹ เชงเชฐเชพเชตเซ‡ เช›เซ‡: 1 2 3 4 5.

เชตเซ‡เชฒ-เชซเซ‡เชก เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเซเชธ เช…เชฅเชตเชพ เชธเซเชชเชฐเซเชงเชพเชคเซเชฎเช• .NET เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎเชฟเช‚เช—

เช†เช•เซƒเชคเชฟเชฎเชพเช‚, เชฅเซเชฐเซ‡เชกเซ‹เชจเซ‡ เช…เชตเชฐเซ‹เชงเชฟเชค เช•เชฐเชตเซเช‚ (เชกเซ‡เชกเชฒเซ‹เช•). เชฒเซ€เชฒเซ‹ - เช…เชฎเชฒ, เชฒเชพเชฒ - เชธเชฟเช‚เช•เซเชฐเชจเชพเช‡เชเซ‡เชถเชจ, เช—เซเชฐเซ‡ - เชฅเซเชฐเซ‡เชก เชธเซ‚เชˆ เชฐเชนเซเชฏเซ‹ เช›เซ‡. เชฐเซ‹เชฎเซเชฌเชธ เช•เชพเชฐเซเชฏเซ‹เชจเซ‹ เชชเซเชฐเชพเชฐเช‚เชญ เชธเชฎเชฏ เชธเซ‚เชšเชตเซ‡ เช›เซ‡.

เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเซเชธเชจเซ€ เชญเซ‚เช–

เชœเซ‹ เช•เซ‡ เช–เชพเชธ เช•เชฐเซ€เชจเซ‡ เชตเชงเซ เช–เซ‹เชฐเชพเช• เชตเชฟเชถเซ‡ เชตเชฟเชšเชพเชฐเชตเซเช‚ เชœเชฐเซ‚เชฐเซ€ เชจเชฅเซ€, เชชเชฐเช‚เชคเซ เชญเซ‚เช– เช•เซ‹เชˆเชจเซ‡ เชชเชฃ เชซเชฟเชฒเชธเซ‚เชซเซ€ เช›เซ‹เชกเซ€ เชฆเซ‡ เช›เซ‡. เชšเชพเชฒเซ‹ เช†เชชเชฃเซ€ เชธเชฎเชธเซเชฏเชพเชฎเชพเช‚ เชฅเซเชฐเซ‡เชกเซ‹เชจเซ€ เชญเซ‚เช–เชฎเชฐเชพเชจเซ€ เชชเชฐเชฟเชธเซเชฅเชฟเชคเชฟเชจเซเช‚ เช…เชจเซเช•เชฐเชฃ เช•เชฐเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซ€เช. เชญเซ‚เช–เชฎเชฐเซ‹ เช เช›เซ‡ เชœเซเชฏเชพเชฐเซ‡ เชฅเซเชฐเซ‡เชก เชšเชพเชฒเซ€ เชฐเชนเซเชฏเซ‹ เช›เซ‡, เชชเชฐเช‚เชคเซ เชจเซ‹เช‚เชงเชชเชพเชคเซเชฐ เช•เชพเชฎ เช•เชฐเซเชฏเชพ เชตเชฟเชจเชพ, เชฌเซ€เชœเชพ เชถเชฌเซเชฆเซ‹เชฎเชพเช‚ เช•เชนเซ€เช เชคเซ‹, เช† เชธเชฎเชพเชจ เชฎเชกเชพเช—เชพเช‚เช  เช›เซ‡, เชซเช•เซเชค เชนเชตเซ‡ เชฅเซเชฐเซ‡เชก เชธเซ‚เชคเซ‹ เชจเชฅเซ€, เชชเชฐเช‚เชคเซ เชธเช•เซเชฐเชฟเชฏเชชเชฃเซ‡ เช–เชพเชตเชพ เชฎเชพเชŸเซ‡ เช•เช‚เชˆเช• เชถเซ‹เชงเซ€ เชฐเชนเซเชฏเซ‹ เช›เซ‡, เชชเชฐเช‚เชคเซ เชคเซเชฏเชพเช‚ เช•เซ‹เชˆ เช–เซ‹เชฐเชพเช• เชจเชฅเซ€. เชตเชพเชฐเช‚เชตเชพเชฐ เช…เชตเชฐเซ‹เชงเชฟเชค เชฅเชตเชพเชฅเซ€ เชฌเชšเชตเชพ เชฎเชพเชŸเซ‡, เชœเซ‹ เช…เชฎเซ‡ เชฌเซ€เชœเซ‹ เชเช• เชจ เชฒเชˆ เชถเช•เซ€เช เชคเซ‹ เช…เชฎเซ‡ เช•เชพเช‚เชŸเซ‹ เชชเชพเช›เซ‹ เชฎเซ‚เช•เซ€เชถเซเช‚.

// ะขะพ ะถะต ั‡ั‚ะพ ะธ ะฒ RunDeadlock, ะฝะพ ั‚ะตะฟะตั€ัŒ ะบะปะฐะดะตะผ ะฒะธะปะบัƒ ะฝะฐะทะฐะด ะธ ะดะพะฑะฐะฒะปัะตะผ ะฟะปะพั…ะธั… ั„ะธะปะพัะพั„ะพะฒ.
private void RunStarvation(int i, CancellationToken token)
{
    while (true)
    {
        bool hasTwoForks = false;
        var waitTime = TimeSpan.FromMilliseconds(50);
        // ะŸะปะพั…ะพะน ั„ะธะปะพัะพั„ะพะฒ ะผะพะถะตั‚ ัƒะถะต ะธะผะตั‚ัŒ ะฒะธะปะบัƒ:
        bool hasLeft = forks[Left(i)] == i + 1;
        if (hasLeft || TakeFork(Left(i), i + 1, waitTime))
        {
            if (TakeFork(Right(i), i + 1, TimeSpan.Zero))
                hasTwoForks = true;
            else
                PutFork(Left(i)); // ะ˜ะฝะพะณะดะฐ ะฟะปะพั…ะพะน ั„ะธะปะพัะพั„ ะพั‚ะดะฐะตั‚ ะฒะธะปะบัƒ ะฝะฐะทะฐะด.
        } 
        if (!hasTwoForks)
        {
            if (token.IsCancellationRequested) break;
            continue;
        }
        eatenFood[i] = (eatenFood[i] + 1) % (int.MaxValue - 1);
        bool goodPhilosopher = i % 2 == 0;
        // ะ ะฟะปะพั…ะพะน ั„ะธะปะพัะพั„ ะทะฐะฑั‹ะฒะฐะตั‚ ะฟะพะปะพะถะธั‚ัŒ ัะฒะพัŽ ะฒะธะปะบัƒ ะพะฑั€ะฐั‚ะฝะพ:
        if (goodPhilosopher)
            PutFork(Left(i));
        // ะ ะตัะปะธ ะธ ะฟั€ะฐะฒัƒัŽ ะฝะต ะฟะพะปะพะถะธั‚, ั‚ะพ ั…ะพั€ะพัˆะธะต ะฑัƒะดัƒั‚ ะฒะพะพะฑั‰ะต ะฑะตะท ะตะดั‹.
        PutFork(Right(i));

        Think(i);

        if (token.IsCancellationRequested)
            break;
    }
}

// ะขะตะฟะตั€ัŒ ะผะพะถะฝะพ ะถะดะฐั‚ัŒ ะพะฟั€ะตะดะตะปะตะฝะฝะพะต ะฒั€ะตะผั.
bool TakeFork(int fork, int philosopher, TimeSpan? waitTime = null)
{
    return SpinWait.SpinUntil(
        () => Interlocked.CompareExchange(ref forks[fork], philosopher, 0) == 0,
              waitTime ?? TimeSpan.FromMilliseconds(-1)
    );
}

เช† เช•เซ‹เชกเชจเซ€ เชฎเชนเชคเซเชตเชจเซ€ เชตเชพเชค เช เช›เซ‡ เช•เซ‡ เชšเชพเชฐเชฎเชพเช‚เชฅเซ€ เชฌเซ‡ เชซเชฟเชฒเชธเซ‚เชซ เชคเซ‡เชฎเชจเชพ เชกเชพเชฌเชพ เช•เชพเช‚เชŸเชพเชจเซ‡ เชจเซ€เชšเซ‡ เชฐเชพเช–เชตเชพเชจเซเช‚ เชญเซ‚เชฒเซ€ เชœเชพเชฏ เช›เซ‡. เช…เชจเซ‡ เชคเซ‡ เชคเชพเชฐเชฃ เช†เชชเซ‡ เช›เซ‡ เช•เซ‡ เชคเซ‡เช“ เชตเชงเซ เช–เซ‹เชฐเชพเช• เช–เชพเชฏ เช›เซ‡, เชœเซเชฏเชพเชฐเซ‡ เช…เชจเซเชฏ เชฒเซ‹เช•เซ‹ เชญเซ‚เช–เซ‡ เชฎเชฐเชตเชพเชจเซเช‚ เชถเชฐเซ‚ เช•เชฐเซ‡ เช›เซ‡, เชœเซ‹ เช•เซ‡ เชฅเซเชฐเซ‡เชกเซ‹ เชธเชฎเชพเชจ เช…เช—เซเชฐเชคเชพ เชงเชฐเชพเชตเซ‡ เช›เซ‡. เช…เชนเซ€เช‚ เชคเซ‡เช“ เชธเช‚เชชเซ‚เชฐเซเชฃเชชเชฃเซ‡ เชญเซ‚เช–เซ‡ เชฎเชฐเชคเชพ เชจเชฅเซ€, เช•เชพเชฐเชฃ เช•เซ‡. เช–เชฐเชพเชฌ เชซเชฟเชฒเชธเซ‚เชซเซ‹ เช•เซเชฏเชพเชฐเซ‡เช• เชคเซ‡เชฎเชจเชพ เช•เชพเช‚เชŸเซ‹ เชชเชพเช›เชพ เชฎเซ‚เช•เซ€ เชฆเซ‡ เช›เซ‡. เชคเซ‡ เชคเชพเชฐเชฃ เช†เชชเซ‡ เช›เซ‡ เช•เซ‡ เชธเชพเชฐเชพ เชฒเซ‹เช•เซ‹ เช–เชฐเชพเชฌ เช•เชฐเชคเชพ 5 เช—เชฃเชพ เช“เช›เชพ เช–เชพเชฏ เช›เซ‡. เชคเซ‡เชฅเซ€ เช•เซ‹เชกเชฎเชพเช‚ เชเช• เชจเชพเชจเซ€ เชญเซ‚เชฒ เช•เชพเชฎเช—เซ€เชฐเซ€เชฎเชพเช‚ เช˜เชŸเชพเชกเซ‹ เชคเชฐเชซ เชฆเซ‹เชฐเซ€ เชœเชพเชฏ เช›เซ‡. เช…เชนเซ€เช‚ เช เชชเชฃ เชจเซ‹เช‚เชงเชตเซเช‚ เชฏเซ‹เช—เซเชฏ เช›เซ‡ เช•เซ‡ เชเช• เชฆเซเชฐเซเชฒเชญ เชชเชฐเชฟเชธเซเชฅเชฟเชคเชฟ เชถเช•เซเชฏ เช›เซ‡ เชœเซเชฏเชพเชฐเซ‡ เชฌเชงเชพ เชซเชฟเชฒเชธเซ‚เชซเซ‹ เชกเชพเชฌเซ‹ เช•เชพเช‚เชŸเซ‹ เชฒเซ‡ เช›เซ‡, เชคเซเชฏเชพเช‚ เช•เซ‹เชˆ เชœเชฎเชฃเซ‹ เชจเชฅเซ€, เชคเซ‡เช“ เชกเชพเชฌเซ€ เชฌเชพเชœเซ เชฎเซ‚เช•เซ‡ เช›เซ‡, เชฐเชพเชน เชœเซเช“, เชซเชฐเซ€เชฅเซ€ เชกเชพเชฌเซ€ เชฌเชพเชœเซ เชฒเซ‹, เชตเช—เซ‡เชฐเซ‡. เช† เชชเชฐเชฟเชธเซเชฅเชฟเชคเชฟ เชชเชฃ เชญเซ‚เช–เชฎเชฐเซ‹ เช›เซ‡, เชตเชงเซ เชฎเชกเชพเช—เชพเช‚เช  เชœเซ‡เชตเซ€. เชนเซเช‚ เชคเซ‡เชจเซ‡ เชชเซเชจเชฐเชพเชตเชฐเซเชคเชจ เช•เชฐเชตเชพเชฎเชพเช‚ เชจเชฟเชทเซเชซเชณ เช—เชฏเซ‹. เชจเซ€เชšเซ‡ เชเชตเซ€ เชชเชฐเชฟเชธเซเชฅเชฟเชคเชฟ เชฎเชพเชŸเซ‡เชจเซเช‚ เชšเชฟเชคเซเชฐ เช›เซ‡ เชœเซเชฏเชพเช‚ เชฌเซ‡ เช–เชฐเชพเชฌ เชซเชฟเชฒเชธเซ‚เชซเซ‹เช เชฌเช‚เชจเซ‡ เช•เชพเช‚เชŸเชพ เชฒเซ€เชงเชพ เช›เซ‡ เช…เชจเซ‡ เชฌเซ‡ เชธเชพเชฐเชพ เชญเซ‚เช–เซเชฏเชพ เช›เซ‡.

เชตเซ‡เชฒ-เชซเซ‡เชก เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเซเชธ เช…เชฅเชตเชพ เชธเซเชชเชฐเซเชงเชพเชคเซเชฎเช• .NET เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎเชฟเช‚เช—

เช…เชนเซ€เช‚ เชคเชฎเซ‡ เชœเซ‹เชˆ เชถเช•เซ‹ เช›เซ‹ เช•เซ‡ เชฅเซเชฐเซ‡เชกเซ‹ เช•เซเชฏเชพเชฐเซ‡เช• เชœเชพเช—เซ‡ เช›เซ‡ เช…เชจเซ‡ เชธเช‚เชธเชพเชงเชจ เชฎเซ‡เชณเชตเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซ‡ เช›เซ‡. เชšเชพเชฐเชฎเชพเช‚เชฅเซ€ เชฌเซ‡ เช•เซ‹เชฐเซ‹ เช•เช‚เชˆ เช•เชฐเชคเชพ เชจเชฅเซ€ (เช‰เชชเชฐเชจเซ‹ เชฒเซ€เชฒเซ‹ เช—เซเชฐเชพเชซ).

เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเชจเซเช‚ เชฎเซƒเชคเซเชฏเซ

เช เซ€เช• เช›เซ‡, เชฌเซ€เชœเซ€ เชธเชฎเชธเซเชฏเชพ เชœเซ‡ เชซเชฟเชฒเชธเซ‚เชซเซ‹เชจเชพ เชญเชตเซเชฏ เชฐเชพเชคเซเชฐเชฟเชญเซ‹เชœเชจเชจเซ‡ เชตเชฟเช•เซเชทเซ‡เชชเชฟเชค เช•เชฐเซ€ เชถเช•เซ‡ เช›เซ‡ เชคเซ‡ เช›เซ‡ เชœเซ‹ เชคเซ‡เชฎเชพเช‚เชฅเซ€ เช•เซ‹เชˆ เช…เชšเชพเชจเช• เชคเซ‡เชจเชพ เชนเชพเชฅเชฎเชพเช‚ เช•เชพเช‚เชŸเซ‹ เชธเชพเชฅเซ‡ เชฎเซƒเชคเซเชฏเซ เชชเชพเชฎเซ‡ เช›เซ‡ (เช…เชจเซ‡ เชคเซ‡เช“ เชคเซ‡เชจเซ‡ เชคเซ‡ เชฐเซ€เชคเซ‡ เชฆเชซเชจเชพเชตเชถเซ‡). เชชเช›เซ€ เชชเชกเซ‹เชถเซ€เช“เชจเซ‡ เชœเชฎเซเชฏเชพ เชตเชฟเชจเชพ เช›เซ‹เชกเซ€ เชฆเซ‡เชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡. เชคเชฎเซ‡ เช† เช•เซ‡เชธ เชฎเชพเชŸเซ‡ เชœเชพเชคเซ‡ เช‰เชฆเชพเชนเชฐเชฃ เช•เซ‹เชก เชธเชพเชฅเซ‡ เช†เชตเซ€ เชถเช•เซ‹ เช›เซ‹, เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เชคเซ‡ เชซเซ‡เช‚เช•เซ€ เชฆเซ‡เชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ NullReferenceException เชซเชฟเชฒเชธเซ‚เชซ เช•เชพเช‚เชŸเซ‹ เชฒเซ‡ เชชเช›เซ€. เช…เชจเซ‡, เชฎเชพเชฐเซเช— เชฆเซเชตเชพเชฐเชพ, เช…เชชเชตเชพเชฆเชจเซ‡ เชจเชฟเชฏเช‚เชคเซเชฐเชฟเชค เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡ เชจเชนเซ€เช‚ เช…เชจเซ‡ เช•เซ‰เชฒเชฟเช‚เช— เช•เซ‹เชก เชซเช•เซเชค เชคเซ‡เชจเซ‡ เชชเช•เชกเชถเซ‡ เชจเชนเซ€เช‚ (เช† เชฎเชพเชŸเซ‡ AppDomain.CurrentDomain.UnhandledException เช…เชจเซ‡ เชตเช—เซ‡เชฐเซ‡). เชคเซ‡เชฅเซ€, เชฅเซเชฐเซ‡เชกเซ‹เชฎเชพเช‚ เช…เชจเซ‡ เช†เช•เชฐเซเชทเช• เชธเชฎเชพเชชเซเชคเชฟ เชธเชพเชฅเซ‡ เชญเซ‚เชฒ เชนเซ‡เชจเซเชกเชฒเชฐเซเชธเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡.

เชตเซ‡เช‡เชŸเชฐ

เช เซ€เช• เช›เซ‡, เช†เชชเชฃเซ‡ เช† เชฎเชกเชพเช—เชพเช‚เช , เชญเซ‚เช–เชฎเชฐเซ‹ เช…เชจเซ‡ เชฎเซƒเชคเซเชฏเซเชจเซ€ เชธเชฎเชธเซเชฏเชพเชจเซ‡ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชนเชฒ เช•เชฐเซ€ เชถเช•เซ€เช? เช…เชฎเซ‡ เชซเช•เซเชค เชเช• เชซเชฟเชฒเชธเซ‚เชซเชจเซ‡ เชซเซ‹เชฐเซเช•เชธ เชธเซเชงเซ€ เชชเชนเซ‹เช‚เชšเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ€เชถเซเช‚, เช† เชธเซเชฅเชพเชจ เชฎเชพเชŸเซ‡ เชฅเซเชฐเซ‡เชกเซ‹เชจเซ‹ เชชเชฐเชธเซเชชเชฐ เชฌเชพเช•เชพเชค เช‰เชฎเซ‡เชฐเซ‹. เชคเซ‡ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชฐเชตเซเช‚? เชงเชพเชฐเซ‹ เช•เซ‡ เชซเชฟเชฒเชธเซ‚เชซเซ‹เชจเซ€ เชฌเชพเชœเซเชฎเชพเช‚ เชเช• เชตเซ‡เชˆเชŸเชฐ เชŠเชญเซ‹ เช›เซ‡, เชœเซ‡ เช•เซ‹เชˆเชชเชฃ เชเช• เชซเชฟเชฒเชธเซ‚เชซเชจเซ‡ เช•เชพเช‚เชŸเซ‹ เชฒเซ‡เชตเชพเชจเซ€ เชชเชฐเชตเชพเชจเช—เซ€ เช†เชชเซ‡ เช›เซ‡. เช…เชฎเซ‡ เช† เชตเซ‡เชˆเชŸเชฐ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชฌเชจเชพเชตเซ€เชถเซเช‚ เช…เชจเซ‡ เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเซ‹ เชคเซ‡เชจเซ‡ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชชเซ‚เช›เชถเซ‡, เชชเซเชฐเชถเซเชจเซ‹ เชฐเชธเชชเซเชฐเชฆ เช›เซ‡.

เชธเซŒเชฅเซ€ เชธเชฐเชณ เชฐเชธเซเชคเซ‹ เช เช›เซ‡ เช•เซ‡ เชœเซเชฏเชพเชฐเซ‡ เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเซ‹ เชซเช•เซเชค เชตเซ‡เชˆเชŸเชฐเชจเซ‡ เช•เชพเช‚เชŸเซ‹เชจเซ€ เชเช•เซเชธเซ‡เชธ เชฎเชพเชŸเซ‡ เชธเชคเชค เชชเซ‚เช›เชถเซ‡. เชคเซ‡. เชนเชตเซ‡ เชซเชฟเชฒเชธเซ‚เชซเซ‹ เชจเชœเซ€เช•เชจเชพ เช•เชพเช‚เชŸเชพเชจเซ€ เชฐเชพเชน เชœเซ‹เชถเซ‡ เชจเชนเซ€เช‚, เชชเชฐเช‚เชคเซ เชฐเชพเชน เชœเซเช“ เช…เชฅเชตเชพ เชตเซ‡เช‡เชŸเชฐเชจเซ‡ เชชเซ‚เช›เซ‹. เชถเชฐเซ‚เช†เชคเชฎเชพเช‚, เช…เชฎเซ‡ เช† เชฎเชพเชŸเซ‡ เชซเช•เซเชค เชฏเซเชเชฐ เชธเซเชชเซ‡เชธเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เช เช›เซ€เช, เชคเซ‡เชฎเชพเช‚ เช…เชฎเซ‡ เช•เชฐเซเชจเชฒเชฎเชพเช‚เชฅเซ€ เช•เซ‹เชˆเชชเชฃ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพเชจเซ‡ เช•เซ‰เชฒ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชตเชฟเช•เซเชทเซ‡เชชเซ‹เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชคเชพ เชจเชฅเซ€ (เชคเซ‡เชฎเชจเชพ เชตเชฟเชถเซ‡ เชจเซ€เชšเซ‡).

เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เชœเช—เซเชฏเชพเชฎเชพเช‚ เช‰เช•เซ‡เชฒเซ‹

เช…เชนเซ€เช‚ เช†เชชเชฃเซ‡ เชเช• เช•เชพเช‚เชŸเซ‹ เช…เชจเซ‡ เชฌเซ‡ เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเซ‹ เชธเชพเชฅเซ‡ เช•เชฐเชคเชพ เชนเชคเชพ เชคเซ‡ เชœ เช•เชฐเซ€เชถเซเช‚, เช†เชชเชฃเซ‡ เชเช• เชšเช•เซเชฐเชฎเชพเช‚ เชธเซเชชเชฟเชจ เช•เชฐเซ€เชถเซเช‚ เช…เชจเซ‡ เชฐเชพเชน เชœเซ‹เชˆเชถเซเช‚. เชชเชฐเช‚เชคเซ เชนเชตเซ‡ เชคเซ‡ เชฌเชงเชพ เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเซ‹ เชนเชถเซ‡ เช…เชจเซ‡, เชœเซ‡เชฎ เชคเซ‡ เชนเชคเชพ, เชฎเชพเชคเซเชฐ เชเช• เชœ เช•เชพเช‚เชŸเซ‹, เชเชŸเชฒเซ‡ เช•เซ‡. เชเชตเซเช‚ เช•เชนเซ€ เชถเช•เชพเชฏ เช•เซ‡ เชตเซ‡เช‡เชŸเชฐ เชชเชพเชธเซ‡เชฅเซ€ เช† โ€œเชธเซ‹เชจเซ‡เชฐเซ€ เช•เชพเช‚เชŸเซ‹โ€ เชฒเซ‡เชจเชพเชฐ เชซเชฟเชฒเชธเซ‚เชซ เชœ เช–เชพเชถเซ‡. เช† เชฎเชพเชŸเซ‡ เช†เชชเชฃเซ‡ SpinLock เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เช เช›เซ€เช.

private static SpinLock spinLock = new SpinLock();  // ะะฐัˆ "ะพั„ะธั†ะธะฐะฝั‚"
private void RunSpinLock(int i, CancellationToken token)
{
    while (true)
    {
        // ะ’ะทะฐะธะผะฝะฐั ะฑะปะพะบะธั€ะพะฒะบะฐ ั‡ะตั€ะตะท busy waiting. ะ’ั‹ะทั‹ะฒะฐะตะผ ะดะพ try, ั‡ั‚ะพะฑั‹
        // ะฒั‹ะฑั€ะฐัะธั‚ัŒ ะธัะบะปัŽั‡ะตะฝะธะต ะฒ ัะปัƒั‡ะฐะต ะพัˆะธะฑะบะธ ะฒ ัะฐะผะพะผ SpinLock.
        bool hasLock = false;
        spinLock.Enter(ref hasLock);
        try
        {
            // ะ—ะดะตััŒ ะผะพะถะตั‚ ะฑั‹ั‚ัŒ ั‚ะพะปัŒะบะพ ะพะดะธะฝ ะฟะพั‚ะพะบ (mutual exclusion).
            forks[Left(i)] = i + 1;  // ะ‘ะตั€ะตะผ ะฒะธะปะบัƒ ัั€ะฐะทัƒ, ะฑะตะท ะพะถะธะดะฐะฝะธั.
            forks[Right(i)] = i + 1;
            eatenFood[i] = (eatenFood[i] + 1) % (int.MaxValue - 1);
            forks[Left(i)] = 0;
            forks[Right(i)] = 0;
        }
        finally
        {
            if(hasLock) spinLock.Exit();  // ะ˜ะทะฑะตะณะฐะตะผ ะฟั€ะพะฑะปะตะผั‹ ัะพ ัะผะตั€ั‚ัŒัŽ ั„ะธะปะพัะพั„ะฐ.
        }

        Think(i);

        if (token.IsCancellationRequested)
            break;
    }
}

SpinLock เช† เชเช• เชฌเซเชฒเซ‹เช•เชฐ เช›เซ‡, เชธเชพเชฅเซ‡, เช†เชถเชฐเซ‡ เช•เชนเซ€เช เชคเซ‹, เชธเชฎเชพเชจ while(true) { if (!lock) break; }, เชชเชฐเช‚เชคเซ เชฎเชพเช‚ เช•เชฐเชคเชพเช‚ เชชเชฃ เชตเชงเซ "เชœเชพเชฆเซ" เชธเชพเชฅเซ‡ SpinWait (เชœเซ‡ เชคเซเชฏเชพเช‚ เชตเชชเชฐเชพเชฏ เช›เซ‡). เชนเชตเซ‡ เชคเซ‡ เชœเชพเชฃเซ‡ เช›เซ‡ เช•เซ‡ เชฐเชพเชน เชœเซ‹เชจเชพเชฐเชพเช“เชจเซ€ เช—เชฃเชคเชฐเซ€ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชฐเชตเซ€, เชคเซ‡เชฎเชจเซ‡ เชฅเซ‹เชกเซ€ เชธเซ‚เชˆ เชœเชตเซเช‚ เช…เชจเซ‡ เชตเชงเซ. เชตเช—เซ‡เชฐเซ‡. เชธเชพเชฎเชพเชจเซเชฏ เชฐเซ€เชคเซ‡, เช‘เชชเซเชŸเชฟเชฎเชพเช‡เช เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชถเช•เซเชฏ เชฌเชงเซเช‚ เช•เชฐเซ‡ เช›เซ‡. เชชเชฐเช‚เชคเซ เช†เชชเชฃเซ‡ เชฏเชพเชฆ เชฐเชพเช–เชตเซเช‚ เชœเซ‹เชˆเช เช•เซ‡ เช† เชนเชœเซ€ เชชเชฃ เช เชœ เชธเช•เซเชฐเชฟเชฏ เชšเช•เซเชฐ เช›เซ‡ เชœเซ‡ เชชเซเชฐเซ‹เชธเซ‡เชธเชฐ เชธเช‚เชธเชพเชงเชจเซ‹เชจเซ‡ เช–เชพเชˆ เชœเชพเชฏ เช›เซ‡ เช…เชจเซ‡ เชชเซเชฐเชตเชพเชนเชจเซ‡ เชœเชพเชณเชตเซ€ เชฐเชพเช–เซ‡ เช›เซ‡, เชœเซ‡ เชญเซ‚เช–เชฎเชฐเซ‹ เชคเชฐเชซ เชฆเซ‹เชฐเซ€ เชถเช•เซ‡ เช›เซ‡ เชœเซ‹ เช•เซ‹เชˆ เชซเชฟเชฒเชธเซ‚เชซ เช…เชจเซเชฏ เช•เชฐเชคเชพ เชตเชงเซ เช…เช—เซเชฐเชคเชพ เชฌเชจเซ€ เชœเชพเชฏ, เชชเชฐเช‚เชคเซ เชคเซ‡เชจเซ€ เชชเชพเชธเซ‡ เชธเซ‹เชจเซ‡เชฐเซ€ เช•เชพเช‚เชŸเซ‹ เชจเชฅเซ€ (เชชเซเชฐเชพเชฏเซ‹เชฐเชฟเชŸเซ€ เชˆเชจเซเชตเชฐเซเชเชจ เชธเชฎเชธเซเชฏเชพ) . เชคเซ‡เชฅเซ€, เช…เชฎเซ‡ เชคเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เชซเช•เซเชค เชตเชนเซ‡เช‚เชšเชพเชฏเซ‡เชฒ เชฎเซ‡เชฎเชฐเซ€เชฎเชพเช‚ เช–เซ‚เชฌ เชœ เชŸเซ‚เช‚เช•เชพ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชฎเชพเชŸเซ‡ เช•เชฐเซ€เช เช›เซ€เช, เช•เซ‹เชˆเชชเชฃ เชคเซƒเชคเซ€เชฏ-เชชเช•เซเชท เช•เซ‰เชฒเซเชธ, เชจเซ‡เชธเซเชŸเซ‡เชก เชฒเซ‰เช•เซเชธ เช…เชจเซ‡ เช…เชจเซเชฏ เช†เชถเซเชšเชฐเซเชฏ เชตเชฟเชจเชพ.

เชตเซ‡เชฒ-เชซเซ‡เชก เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเซเชธ เช…เชฅเชตเชพ เชธเซเชชเชฐเซเชงเชพเชคเซเชฎเช• .NET เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎเชฟเช‚เช—

เชฎเชพเชŸเซ‡ เชšเชฟเชคเซเชฐเช•เชพเชฎ SpinLock. เชธเซเชŸเซเชฐเซ€เชฎเซเชธ เชธเซ‹เชจเซ‡เชฐเซ€ เช•เชพเช‚เชŸเซ‹ เชฎเชพเชŸเซ‡ เชธเชคเชค "เชฒเชกเชพเชˆ" เช›เซ‡. เชจเชฟเชทเซเชซเชณเชคเชพเช“ เช›เซ‡ - เช†เช•เซƒเชคเชฟเชฎเชพเช‚, เชชเชธเช‚เชฆ เช•เชฐเซ‡เชฒ เชตเชฟเชธเซเชคเชพเชฐ. เช•เซ‹เชฐเซ‹เชจเซ‹ เชธเช‚เชชเซ‚เชฐเซเชฃ เช‰เชชเชฏเซ‹เช— เชฅเชคเซ‹ เชจเชฅเซ€: เช† เชšเชพเชฐ เชฅเซเชฐเซ‡เชกเซ‹ เชฆเซเชตเชพเชฐเชพ เชฎเชพเชคเซเชฐ 2/3.

เช…เชนเซ€เช‚ เช…เชจเซเชฏ เช‰เช•เซ‡เชฒ เชฎเชพเชคเซเชฐ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชนเชถเซ‡ Interlocked.CompareExchange เช‰เชชเชฐเชจเชพ เช•เซ‹เชกเชฎเชพเช‚ (เชญเซ‚เช–เซเชฏเชพ เชคเชคเซเชตเชœเซเชžเชพเชจเซ€เช“เชฎเชพเช‚) เชฌเชคเชพเชตเซเชฏเชพ เชชเซเชฐเชฎเชพเชฃเซ‡ เชธเชฎเชพเชจ เชธเช•เซเชฐเชฟเชฏ เชชเซเชฐเชคเซ€เช•เซเชทเชพ เชธเชพเชฅเซ‡, เชชเชฐเช‚เชคเซ เช†, เชชเชนเซ‡เชฒเซ‡เชฅเซ€ เชœ เช•เชนเซเชฏเซเช‚ เชคเซ‡เชฎ, เชธเซˆเชฆเซเชงเชพเช‚เชคเชฟเช• เชฐเซ€เชคเซ‡ เช…เชตเชฐเซ‹เชงเชฟเชค เชฅเชˆ เชถเช•เซ‡ เช›เซ‡.

เชชเชฐ Interlocked เช เชจเซ‹เช‚เชงเชตเซเช‚ เชœเซ‹เช‡เช เช•เซ‡ เชคเซเชฏเชพเช‚ เชฎเชพเชคเซเชฐ เชจเชฅเซ€ CompareExchange, เชชเชฃ เช…เชฃเซ เชตเชพเช‚เชšเชตเชพ เช…เชจเซ‡ เชฒเช–เชตเชพ เชฎเชพเชŸเซ‡เชจเซ€ เช…เชจเซเชฏ เชชเชฆเซเชงเชคเชฟเช“. เช…เชจเซ‡ เชฌเชฆเชฒเชพเชตเชจเชพ เชชเซเชจเชฐเชพเชตเชฐเซเชคเชจ เชฆเซเชตเชพเชฐเชพ, เชœเซ‹ เชฌเซ€เชœเชพ เชฅเซเชฐเซ‡เชกเชฎเชพเช‚ เชคเซ‡เชจเชพ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชธเชฎเชฏ เชนเซ‹เชฏ (เชตเชพเช‚เชšเซ‹ 1, เชตเชพเช‚เชšเซ‹ 2, เชฒเช–เซ‹ 2, เชฒเช–เซ‹ 1 เช–เชฐเชพเชฌ เช›เซ‡), เชคเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เชเช• เชฎเซ‚เชฒเซเชฏเชฎเชพเช‚ เชœเชŸเชฟเชฒ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชฎเชพเชŸเซ‡ เชฅเชˆ เชถเช•เซ‡ เช›เซ‡ (เช‡เชจเซเชŸเชฐเชฒเซ‹เช•เซเชก เชเชจเชฟเชฅเชฟเช‚เช— เชชเซ‡เชŸเชฐเซเชจ).

เช•เชฐเซเชจเชฒ เชฎเซ‹เชก เชธเซ‹เชฒเซเชฏเซเชถเชจเซเชธ

เชฒเซ‚เชชเชฎเชพเช‚ เชธเช‚เชธเชพเชงเชจเซ‹เชจเซ‹ เชฌเช—เชพเชก เชŸเชพเชณเชตเชพ เชฎเชพเชŸเซ‡, เชšเชพเชฒเซ‹ เชœเซ‹เชˆเช เช•เซ‡ เช†เชชเชฃเซ‡ เชฅเซเชฐเซ‡เชกเชจเซ‡ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช…เชตเชฐเซ‹เชงเชฟเชค เช•เชฐเซ€ เชถเช•เซ€เช. เชฌเซ€เชœเชพ เชถเชฌเซเชฆเซ‹เชฎเชพเช‚ เช•เชนเซ€เช เชคเซ‹, เช…เชฎเชพเชฐเซเช‚ เช‰เชฆเชพเชนเชฐเชฃ เชšเชพเชฒเซ เชฐเชพเช–เซ€เชจเซ‡, เชšเชพเชฒเซ‹ เชœเซ‹เชˆเช เช•เซ‡ เชตเซ‡เชˆเชŸเชฐ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเชจเซ‡ เชธเซ‚เชˆ เชœเชพเชฏ เช›เซ‡ เช…เชจเซ‡ เชœเซเชฏเชพเชฐเซ‡ เชœเชฐเซ‚เชฐเซ€ เชนเซ‹เชฏ เชคเซเชฏเชพเชฐเซ‡ เชœ เชคเซ‡เชจเซ‡ เชœเช—เชพเชกเซ‡ เช›เซ‡. เชชเซเชฐเชฅเชฎ, เชšเชพเชฒเซ‹ เชœเซ‹เชˆเช เช•เซ‡ เช“เชชเชฐเซ‡เชŸเชฟเช‚เช— เชธเชฟเชธเซเชŸเชฎเชจเชพ เช•เชฐเซเชจเชฒ เชฎเซ‹เชก เชฆเซเชตเชพเชฐเชพ เช† เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชฐเชตเซเช‚. เชคเซเชฏเชพเช‚เชจเซ€ เชคเชฎเชพเชฎ เชฐเชšเชจเชพเช“ เช˜เชฃเซ€ เชตเช–เชค เชฏเซเชเชฐ เชธเซเชชเซ‡เชธ เช•เชฐเชคเชพเช‚ เชงเซ€เชฎเซ€ เชนเซ‹เชฏ เช›เซ‡. เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เช˜เชฃเซ€ เชตเช–เชค เชงเซ€เชฎเซเช‚ AutoResetEvent เช•เชฆเชพเชš 53 เช—เชฃเซ‹ เชงเซ€เชฎเซ‹ SpinLock [เชฐเชฟเช•เซเชŸเชฐ]. เชชเชฐเช‚เชคเซ เชคเซ‡เชฎเชจเซ€ เชธเชนเชพเชฏเชฅเซ€, เชคเชฎเซ‡ เชธเชฎเช—เซเชฐ เชธเชฟเชธเซเชŸเชฎเชฎเชพเช‚ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพเช“เชจเซ‡ เชธเซเชฎเซ‡เชณ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹, เชตเซเชฏเชตเชธเซเชฅเชพเชชเชฟเชค เช›เซ‡ เช•เซ‡ เชจเชนเซ€เช‚.

เช…เชนเซ€เช‚เชจเซเช‚ เชฎเซ‚เชณ เชฌเชพเช‚เชงเช•เชพเชฎ เช…เชกเชงเซ€ เชธเชฆเซ€ เชชเชนเซ‡เชฒเชพเช‚ เชกเชฟเชœเช•เซเชธเซเชŸเซเชฐเชพ เชฆเซเชตเชพเชฐเชพ เชชเซเชฐเชธเซเชคเชพเชตเชฟเชค เชธเซ‡เชฎเชพเชซเซ‹เชฐ เช›เซ‡. เชธเซ‡เชฎเชพเชซเซ‹เชฐ, เชธเชฐเชณ เชถเชฌเซเชฆเซ‹เชฎเชพเช‚ เช•เชนเซ€เช เชคเซ‹, เชธเชฟเชธเซเชŸเชฎ เชฆเซเชตเชพเชฐเชพ เชธเช‚เชšเชพเชฒเชฟเชค เชเช• เชธเช•เชพเชฐเชพเชคเซเชฎเช• เชชเซ‚เชฐเซเชฃเชพเช‚เช• เช›เซ‡, เช…เชจเซ‡ เชคเซ‡เชจเชพ เชชเชฐ เชฌเซ‡ เช•เชพเชฎเช—เซ€เชฐเซ€, เชตเชงเชพเชฐเซ‹ เช…เชจเซ‡ เช˜เชŸเชพเชกเซ‹. เชœเซ‹ เชคเซ‡ เช˜เชŸเชพเชกเชตเชพเชฎเชพเช‚ เชจเชฟเชทเซเชซเชณ เชœเชพเชฏ, เชถเซ‚เชจเซเชฏ, เชคเซ‹ เช•เซ‰เชฒเชฟเช‚เช— เชฅเซเชฐเซ‡เชก เช…เชตเชฐเซ‹เชงเชฟเชค เช›เซ‡. เชœเซเชฏเชพเชฐเซ‡ เช•เซ‹เชˆ เช…เชจเซเชฏ เชธเช•เซเชฐเชฟเชฏ เชฅเซเชฐเซ‡เชก/เชชเซเชฐเช•เซเชฐเชฟเชฏเชพ เชฆเซเชตเชพเชฐเชพ เชธเช‚เช–เซเชฏเชพ เชตเชงเชพเชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡, เชคเซเชฏเชพเชฐเซ‡ เชฅเซเชฐเซ‡เชกเซ‹ เช›เซ‹เชกเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ เช…เชจเซ‡ เชชเชพเชธ เช•เชฐเซ‡เชฒ เชธเช‚เช–เซเชฏเชพ เชฆเซเชตเชพเชฐเชพ เชธเซ‡เชฎเชพเชซเซ‹เชฐ เชซเชฐเซ€เชฅเซ€ เช˜เชŸเซ‡ เช›เซ‡. เช•เซ‹เชˆ เชธเซ‡เชฎเชพเชซเซ‹เชฐ เชธเชพเชฅเซ‡ เช…เชกเชšเชฃเชฎเชพเช‚ เชฐเชนเซ‡เชฒเซ€ เชŸเซเชฐเซ‡เชจเซ‹เชจเซ€ เช•เชฒเซเชชเชจเชพ เช•เชฐเซ€ เชถเช•เซ‡ เช›เซ‡. .NET เชธเชฎเชพเชจ เช•เชพเชฐเซเชฏเช•เซเชทเชฎเชคเชพ เชธเชพเชฅเซ‡ เช…เชจเซ‡เช• เชฐเชšเชจเชพเช“ เช“เชซเชฐ เช•เชฐเซ‡ เช›เซ‡: AutoResetEvent, ManualResetEvent, Mutex เช…เชจเซ‡ เชฎเชพเชฐเซ€ เชœเชพเชคเชจเซ‡ Semaphore. เช…เชฎเซ‡ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชถเซเช‚ AutoResetEvent, เช† เชฌเชพเช‚เชงเช•เชพเชฎเซ‹เชฎเชพเช‚ เช† เชธเซŒเชฅเซ€ เชธเชฐเชณ เช›เซ‡: เชซเช•เซเชค เชฌเซ‡ เชฎเซ‚เชฒเซเชฏเซ‹ 0 เช…เชจเซ‡ 1 (เช–เซ‹เชŸเซเช‚, เชธเชพเชšเซเช‚). เชคเซ‡เชฃเซ€เชจเซ€ เชชเชฆเซเชงเชคเชฟ WaitOne() เชœเซ‹ เชฎเซ‚เชฒเซเชฏ 0 เชนเซ‹เชฏ เชคเซ‹ เช•เซ‰เชฒเชฟเช‚เช— เชฅเซเชฐเซ‡เชกเชจเซ‡ เช…เชตเชฐเซ‹เชงเชฟเชค เช•เชฐเซ‡ เช›เซ‡, เช…เชจเซ‡ เชœเซ‹ 1, เชคเซ‹ เชคเซ‡เชจเซ‡ 0 เชธเซเชงเซ€ เช˜เชŸเชพเชกเซ‡ เช›เซ‡ เช…เชจเซ‡ เชคเซ‡เชจเซ‡ เช›เซ‹เชกเซ€ เชฆเซ‡ เช›เซ‡. เชเช• เชชเชฆเซเชงเชคเชฟ Set() 1 เชธเซเชงเซ€ เชตเชงเซ‡ เช›เซ‡ เช…เชจเซ‡ เชเช• เชตเซ‡เชˆเชŸเชฐเชจเซ‡ เชชเชธเชพเชฐ เชฅเชตเชพ เชฆเซ‡ เช›เซ‡, เชœเซ‡ เชซเชฐเซ€เชฅเซ€ 0 เชธเซเชงเซ€ เช˜เชŸเชพเชกเซ‡ เช›เซ‡. เชธเชฌเชตเซ‡ เชŸเชฐเซเชจเชธเซเชŸเชพเชˆเชฒเชจเซ€ เชœเซ‡เชฎ เช•เชพเชฐเซเชฏ เช•เชฐเซ‡ เช›เซ‡.

เชšเชพเชฒเซ‹ เช‰เช•เซ‡เชฒเชจเซ‡ เชœเชŸเชฟเชฒ เชฌเชจเชพเชตเซ€เช เช…เชจเซ‡ เชฆเชฐเซ‡เช• เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐ เชฎเชพเชŸเซ‡ เชฒเซ‰เช•เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เช, เช…เชจเซ‡ เชเช• เชœ เชธเชฎเชฏเซ‡ เชฌเชงเชพ เชฎเชพเชŸเซ‡ เชจเชนเซ€เช‚. เชคเซ‡. เชนเชตเซ‡ เชเช• เชธเชพเชฅเซ‡ เช…เชจเซ‡เช• เชซเชฟเชฒเชธเซ‚เชซเซ‹ เชนเซ‹เชˆ เชถเช•เซ‡ เช›เซ‡, เชเช• เชจเชนเซ€เช‚. เชชเชฐเช‚เชคเซ เช…เชฎเซ‡ เชซเชฐเซ€เชฅเซ€ เชŸเซ‡เชฌเชฒเชจเซ€ เชเช•เซเชธเซ‡เชธเชจเซ‡ เชฏเซ‹เช—เซเชฏ เชฐเซ€เชคเซ‡ เช…เชตเชฐเซ‹เชงเชฟเชค เช•เชฐเซ€เช เช›เซ€เช, เชฐเซ‡เชธ (เชœเชพเชคเชฟเชจเซ€ เชธเซเชฅเชฟเชคเชฟ) เชŸเชพเชณเชตเชพ, เช–เชพเชคเชฐเซ€เชชเซ‚เชฐเซเชตเช• เชฌเซ‡เชŸเซเชธ เชฒเซ‡เชตเชพ.

// ะ”ะปั ะฑะปะพะบะธั€ะพะฒะฐะฝะธั ะพั‚ะดะตะปัŒะฝะพะณะพ ั„ะธะปะพัะพั„ะฐ.
// ะ˜ะฝะธั†ะธะฐะปะธะทะธั€ัƒะตั‚ัั: new AutoResetEvent(true) ะดะปั ะบะฐะถะดะพะณะพ.
private AutoResetEvent[] philosopherEvents;

// ะ”ะปั ะดะพัั‚ัƒะฟะฐ ะบ ะฒะธะปะบะฐะผ / ะดะพัั‚ัƒะฟ ะบ ัั‚ะพะปัƒ.
private AutoResetEvent tableEvent = new AutoResetEvent(true);

// ะ ะพะถะดะตะฝะธะต ั„ะธะปะพัะพั„ะฐ.
public void Run(int i, CancellationToken token)
{
    while (true)
    {
        TakeForks(i); // ะ–ะดะตั‚ ะฒะธะปะบะธ.
        // ะžะฑะตะด. ะœะพะถะตั‚ ะฑั‹ั‚ัŒ ะธ ะดะพะปัŒัˆะต.
        eatenFood[i] = (eatenFood[i] + 1) % (int.MaxValue - 1);
        PutForks(i); // ะžั‚ะดะฐั‚ัŒ ะฒะธะปะบะธ ะธ ั€ะฐะทะฑะปะพะบะธั€ะพะฒะฐั‚ัŒ ัะพัะตะดะตะน.
        Think(i);
        if (token.IsCancellationRequested) break;
    }
}

// ะžะถะธะดะฐั‚ัŒ ะฒะธะปะบะธ ะฒ ะฑะปะพะบะธั€ะพะฒะบะต.
void TakeForks(int i)
{
    bool hasForks = false;
    while (!hasForks) // ะŸะพะฟั€ะพะฑะพะฒะฐั‚ัŒ ะตั‰ะต ั€ะฐะท (ะฑะปะพะบะธั€ะพะฒะบะฐ ะฝะต ะทะดะตััŒ).
    {
        // ะ˜ัะบะปัŽั‡ะฐัŽั‰ะธะน ะดะพัั‚ัƒะฟ ะบ ัั‚ะพะปัƒ, ะฑะตะท ะณะพะฝะพะบ ะทะฐ ะฒะธะปะบะฐะผะธ.
        tableEvent.WaitOne();
        if (forks[Left(i)] == 0 && forks[Right(i)] == 0)
            forks[Left(i)] = forks[Right(i)] = i + 1;
        hasForks = forks[Left(i)] == i + 1 && forks[Right(i)] == i + 1;
        if (hasForks)
            // ะขะตะฟะตั€ัŒ ั„ะธะปะพัะพั„ ะฟะพะตัั‚, ะฒั‹ะนะดะตั‚ ะธะท ั†ะธะบะปะฐ. ะ•ัะปะธ Set 
            // ะฒั‹ะทะฒะฐะฝ ะดะฒะฐะถะดั‹, ั‚ะพ ะทะฝะฐั‡ะตะฝะธะต true.
            philosopherEvents[i].Set();
        // ะ ะฐะทะฑะปะพะบะธั€ะพะฒะฐั‚ัŒ ะพะดะฝะพะณะพ ะพะถะธะดะฐัŽั‰ะตะณะพ. ะŸะพัะปะต ะฝะตะณะพ ะทะฝะฐั‡ะตะฝะธะต tableEvent ะฒ false.
        tableEvent.Set(); 
        // ะ•ัะปะธ ะธะผะตะตั‚ true, ะฝะต ะฑะปะพะบะธั€ัƒะตั‚ัั, ะฐ ะตัะปะธ false, ั‚ะพ ะฑัƒะดะตั‚ ะถะดะฐั‚ัŒ Set ะพั‚ ัะพัะตะดะฐ.
        philosopherEvents[i].WaitOne();
    }
}

// ะžั‚ะดะฐั‚ัŒ ะฒะธะปะบะธ ะธ ั€ะฐะทะฑะปะพะบะธั€ะพะฒะฐั‚ัŒ ัะพัะตะดะตะน.
void PutForks(int i)
{
    tableEvent.WaitOne(); // ะ‘ะตะท ะณะพะฝะพะบ ะทะฐ ะฒะธะปะบะฐะผะธ.
    forks[Left(i)] = 0;
    // ะŸั€ะพะฑัƒะดะธั‚ัŒ ะปะตะฒะพะณะพ, ะฐ ะฟะพั‚ะพะผ ะธ ะฟั€ะฐะฒะพะณะพ ัะพัะตะดะฐ, ะปะธะฑะพ AutoResetEvent ะฒ true.
    philosopherEvents[LeftPhilosopher(i)].Set();
    forks[Right(i)] = 0;
    philosopherEvents[RightPhilosopher(i)].Set();
    tableEvent.Set();
}

เช…เชนเซ€เช‚ เชถเซเช‚ เชฅเชˆ เชฐเชนเซเชฏเซเช‚ เช›เซ‡ เชคเซ‡ เชธเชฎเชœเชตเชพ เชฎเชพเชŸเซ‡, เชœเซเชฏเชพเชฐเซ‡ เชซเชฟเชฒเชธเซ‚เชซ เชซเซ‹เชฐเซเช•เชธ เชฒเซ‡เชตเชพเชฎเชพเช‚ เชจเชฟเชทเซเชซเชณ เช—เชฏเซ‹ เชคเซเชฏเชพเชฐเซ‡ เช•เซ‡เชธเชจเซ‡ เชงเซเชฏเชพเชจเชฎเชพเช‚ เชฒเซ‹, เชชเช›เซ€ เชคเซ‡เชจเซ€ เช•เซเชฐเชฟเชฏเชพเช“ เชจเซ€เชšเซ‡ เชฎเซเชœเชฌ เชนเชถเซ‡. เชคเซ‡ เชŸเซ‡เชฌเชฒ เชชเชฐ เชชเชนเซ‹เช‚เชšเชตเชพเชจเซ€ เชฐเชพเชน เชœเซ‹เชˆ เชฐเชนเซเชฏเซ‹ เช›เซ‡. เชคเซ‡ เชชเซเชฐเชพเชชเซเชค เช•เชฐเซเชฏเชพ เชชเช›เซ€, เชคเซ‡ เช•เชพเช‚เชŸเซ‹ เชฒเซ‡เชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซ‡ เช›เซ‡. เช•เชพเชฎ เช•เชฐเซเชฏเซเช‚ เชจเชฅเซ€. เชคเซ‡ เชŸเซ‡เชฌเชฒเชจเซ€ เชเช•เซเชธเซ‡เชธ เช†เชชเซ‡ เช›เซ‡ (เชชเชฐเชธเซเชชเชฐ เชฌเชพเช•เชพเชค). เช…เชจเซ‡ เชคเซ‡เชจเซ€ "เชŸเชฐเซเชจเชธเซเชŸเชพเช‡เชฒ" เชชเชธเชพเชฐ เช•เชฐเซ‡ เช›เซ‡ (AutoResetEvent) (เชคเซ‡เช“ เชถเชฐเซ‚เช†เชคเชฎเชพเช‚ เช–เซเชฒเซเชฒเชพ เช›เซ‡). เชคเซ‡ เชซเชฐเซ€เชฅเซ€ เชšเช•เซเชฐเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡, เช•เชพเชฐเชฃ เช•เซ‡ เชคเซ‡เชจเซ€ เชชเชพเชธเซ‡ เช•เชพเช‚เชŸเซ‹ เชจเชฅเซ€. เชคเซ‡ เชคเซ‡เชฎเชจเซ‡ เชฒเซ‡เชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซ‡ เช›เซ‡ เช…เชจเซ‡ เชคเซ‡เชจเชพ "เชŸเชฐเซเชจเชธเซเชŸเชพเช‡เชฒ" เชชเชฐ เช…เชŸเช•เซ€ เชœเชพเชฏ เช›เซ‡. เชœเชฎเชฃเซ€ เช•เซ‡ เชกเชพเชฌเซ€ เชฌเชพเชœเซเชจเชพ เช•เซ‡เชŸเชฒเชพเช• เชตเชงเซ เชจเชธเซ€เชฌเชฆเชพเชฐ เชชเชพเชกเซ‹เชถเซ€, เช–เชพเชตเซเช‚ เชธเชฎเชพเชชเซเชค เช•เชฐเซเชฏเชพ เชชเช›เซ€, เช…เชฎเชพเชฐเชพ เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเชจเซ‡ "เชคเซ‡เชฎเชจเซ€ เชŸเชฐเซเชจเชธเซเชŸเชพเช‡เชฒ เช–เซ‹เชฒเซ€เชจเซ‡" เช–เซ‹เชฒเซ‡ เช›เซ‡. เช†เชชเชฃเชพ เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐ เชฌเซ€เชœเซ€ เชตเชพเชฐ เชคเซ‡เชจเซ‡ เชชเชธเชพเชฐ เช•เชฐเซ‡ เช›เซ‡ (เช…เชจเซ‡ เชคเซ‡ เชคเซ‡เชจเซ€ เชชเชพเช›เชณ เชฌเช‚เชง เชฅเชพเชฏ เช›เซ‡). เชคเซ‡ เชคเซเชฐเซ€เชœเซ€ เชตเช–เชค เช•เชพเช‚เชŸเซ‹ เชฒเซ‡เชตเชพเชจเซ‹ เชชเซเชฐเชฏเชคเซเชจ เช•เชฐเซ‡ เช›เซ‡. เชธเชพเชฐเชพ เชจเชธเซ€เชฌ. เช…เชจเซ‡ เชคเซ‡ เชœเชฎเชตเชพ เชฎเชพเชŸเซ‡ เชคเซ‡เชจเซ€ เชŸเชฐเซเชจเชธเซเชŸเชพเช‡เชฒ เชชเชธเชพเชฐ เช•เชฐเซ‡ เช›เซ‡.

เชœเซเชฏเชพเชฐเซ‡ เช†เชตเชพ เช•เซ‹เชกเชฎเชพเช‚ เชฐเซ‡เชจเซเชกเชฎ เชญเซ‚เชฒเซ‹ เชนเซ‹เชฏ เช›เซ‡ (เชคเซ‡ เชนเช‚เชฎเซ‡เชถเชพ เช…เชธเซเชคเชฟเชคเซเชตเชฎเชพเช‚ เชนเซ‹เชฏ เช›เซ‡), เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เชชเชพเชกเซ‹เชถเซ€เชจเซ‡ เช–เซ‹เชŸเซ€ เชฐเซ€เชคเซ‡ เช‰เชฒเซเชฒเซ‡เช–เชฟเชค เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ เช…เชฅเชตเชพ เชคเซ‡ เชœ เช‘เชฌเซเชœเซ‡เช•เซเชŸ เชฌเชจเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ AutoResetEvent เชฌเชงเชพ เชฎเชพเชŸเซ‡ (Enumerable.Repeat), เชชเช›เซ€ เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเซ‹ เชตเชฟเช•เชพเชธเช•เชฐเซเชคเชพเช“เชจเซ€ เชฐเชพเชน เชœเซ‹เชถเซ‡, เช•เชพเชฐเชฃ เช•เซ‡ เช†เชตเชพ เช•เซ‹เชกเชฎเชพเช‚ เชญเซ‚เชฒเซ‹ เชถเซ‹เชงเชตเซ€ เช เช–เซ‚เชฌ เชฎเซเชถเซเช•เซ‡เชฒ เช•เชพเชฐเซเชฏ เช›เซ‡. เช† เช‰เช•เซ‡เชฒ เชธเชพเชฅเซ‡เชจเซ€ เชฌเซ€เชœเซ€ เชธเชฎเชธเซเชฏเชพ เช เช›เซ‡ เช•เซ‡ เชคเซ‡ เช–เชพเชคเชฐเซ€ เช†เชชเชคเซเช‚ เชจเชฅเซ€ เช•เซ‡ เช•เซ‹เชˆ เชซเชฟเชฒเชธเซ‚เชซ เชญเซ‚เช–เซ‡ เชฎเชฐเชถเซ‡ เชจเชนเซ€เช‚.

เชนเชพเช‡เชฌเซเชฐเชฟเชก เชธเซ‹เชฒเซเชฏเซเชถเชจเซเชธ

เช…เชฎเซ‡ เชธเชฎเชฏ เชฎเชพเชŸเซ‡เชจเชพ เชฌเซ‡ เช…เชญเชฟเช—เชฎเซ‹ เชœเซ‹เชฏเชพ เช›เซ‡, เชœเซเชฏเชพเชฐเซ‡ เช…เชฎเซ‡ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เชฎเซ‹เชก เช…เชจเซ‡ เชฒเซ‚เชชเชฎเชพเช‚ เชฐเชนเซ€เช เช›เซ€เช, เช…เชจเซ‡ เชœเซเชฏเชพเชฐเซ‡ เช…เชฎเซ‡ เช•เชฐเซเชจเชฒ เชฆเซเชตเชพเชฐเชพ เชฅเซเชฐเซ‡เชกเชจเซ‡ เช…เชตเชฐเซ‹เชงเชฟเชค เช•เชฐเซ€เช เช›เซ€เช. เชชเซเชฐเชฅเชฎ เชชเชฆเซเชงเชคเชฟ เชŸเซ‚เช‚เช•เชพ เชคเชพเชณเชพเช“ เชฎเชพเชŸเซ‡ เชธเชพเชฐเซ€ เช›เซ‡, เชฌเซ€เชœเซ€ เชฒเชพเช‚เชฌเซ€ เชฐเชพเชถเชฟเช“ เชฎเชพเชŸเซ‡. เชฒเซ‚เชชเชฎเชพเช‚ เชฌเชฆเชฒเชพเชต เชฎเชพเชŸเซ‡ เชตเซ‡เชฐเซ€เชเชฌเชฒเชจเซ€ เชชเซเชฐเชฅเชฎ เชธเช‚เช•เซเชทเชฟเชชเซเชคเชฎเชพเช‚ เชฐเชพเชน เชœเซ‹เชตเซ€ เช˜เชฃเซ€เชตเชพเชฐ เชœเชฐเซ‚เชฐเซ€ เช›เซ‡, เช…เชจเซ‡ เชชเช›เซ€ เชœเซเชฏเชพเชฐเซ‡ เชฐเชพเชน เชฒเชพเช‚เชฌเซ€ เชนเซ‹เชฏ เชคเซเชฏเชพเชฐเซ‡ เชฅเซเชฐเซ‡เชกเชจเซ‡ เช…เชตเชฐเซ‹เชงเชฟเชค เช•เชฐเซ‹. เช† เช…เชญเชฟเช—เชฎ เช•เชนเซ‡เชตเชพเชคเชพ เชฎเชพเช‚ เชฒเชพเช—เซ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡. เชตเชฐเซเชฃเชธเช‚เช•เชฐ เชฐเชšเชจเชพเช“. เช…เชนเซ€เช‚ เช•เชฐเซเชจเชฒ เชฎเซ‹เชก เชฎเชพเชŸเซ‡ เชธเชฎเชพเชจ เชฐเชšเชจเชพเช“ เช›เซ‡, เชชเชฐเช‚เชคเซ เชนเชตเซ‡ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เชฎเซ‹เชก เชฒเซ‚เชช เชธเชพเชฅเซ‡: SemaphorSlim, ManualResetEventSlim เชตเช—เซ‡เชฐเซ‡. เช…เชนเซ€เช‚เชจเซ€ เชธเซŒเชฅเซ€ เชฒเซ‹เช•เชชเซเชฐเชฟเชฏ เชกเชฟเชเชพเช‡เชจ เช›เซ‡ Monitor, เช•เชพเชฐเชฃ เช•เซ‡ C# เชฎเชพเช‚ เชเช• เชœเชพเชฃเซ€เชคเซเช‚ เช›เซ‡ lock เชตเชพเช•เซเชฏเชฐเชšเชจเชพ Monitor เช† เช เชœ เชธเซ‡เชฎเชพเชซเซ‹เชฐ เช›เซ‡ เชœเซ‡เชจเซ€ เชฎเชนเชคเซเชคเชฎ เช•เชฟเช‚เชฎเชค 1 (เชฎเซเชฏเซเชŸเซ‡เช•เซเชธ) เช›เซ‡, เชชเชฐเช‚เชคเซ เชฒเซ‚เชช, เชฐเชฟเช•เชฐเซเชเชจ, เช•เชจเซเชกเชฟเชถเชจ เชตเซ‡เชฐเซ€เชเชฌเชฒ เชชเซ‡เชŸเชฐเซเชจ (เชจเซ€เชšเซ‡ เชคเซ‡เชจเชพ เชชเชฐ เชตเชงเซ), เชตเช—เซ‡เชฐเซ‡เชฎเชพเช‚ เชฐเชพเชน เชœเซ‹เชตเชพ เชฎเชพเชŸเซ‡ เชธเชชเซ‹เชฐเซเชŸ เชธเชพเชฅเซ‡. เชšเชพเชฒเซ‹ เชคเซ‡เชจเซ€ เชธเชพเชฅเซ‡ เช‰เช•เซ‡เชฒ เชœเซ‹เชˆเช.

// ะกะฟั€ัั‡ะตะผ ะพะฑัŠะตะบั‚ ะดะปั ะœะพะฝะธั‚ะพั€ะฐ ะพั‚ ะฒัะตั…, ั‡ั‚ะพะฑั‹ ะฑะตะท ะดะตะดะปะพะบะพะฒ.
private readonly object _lock = new object();
// ะ’ั€ะตะผั ะพะถะธะดะฐะฝะธั ะฟะพั‚ะพะบะฐ.
private DateTime?[] _waitTimes = new DateTime?[philosophersAmount];

public void Run(int i, CancellationToken token)
{
    while (true)
    {
        TakeForks(i);
        eatenFood[i] = (eatenFood[i] + 1) % (int.MaxValue - 1);
        PutForks(i);
        Think(i);
        if (token.IsCancellationRequested) break;
    }
}

// ะะฐัˆะต ัะปะพะถะฝะพะต ัƒัะปะพะฒะธะต ะดะปั Condition Variable ะฟะฐั‚ั‚ะตั€ะฝะฐ.
bool CanIEat(int i)
{
    // ะ•ัะปะธ ะตัั‚ัŒ ะฒะธะปะบะธ:
    if (forks[Left(i)] != 0 && forks[Right(i)] != 0)
        return false;
    var now = DateTime.Now;
    // ะœะพะถะตั‚, ะตัะปะธ ัะพัะตะดะธ ะฝะต ะฑะพะปะตะต ะณะพะปะพะดะฝั‹ะต, ั‡ะตะผ ั‚ะตะบัƒั‰ะธะน.
    foreach(var p in new int[] {LeftPhilosopher(i), RightPhilosopher(i)})
        if (_waitTimes[p] != null && now - _waitTimes[p] > now - _waitTimes[i])
            return false;
    return true;
}

void TakeForks(int i)
{
    // ะ—ะฐะนั‚ะธ ะฒ ะœะพะฝะธั‚ะพั€. ะขะพ ะถะต ัะฐะผะพะต: lock(_lock) {..}.
    // ะ’ั‹ะทั‹ะฒะฐะตะผ ะฒะฝะต try, ั‡ั‚ะพะฑั‹ ะฒะพะทะผะพะถะฝะพะต ะธัะบะปัŽั‡ะตะฝะธะต ะฒั‹ะฑั€ะฐัั‹ะฒะฐะปะพััŒ ะฒั‹ัˆะต.
    bool lockTaken = false;
    Monitor.Enter(_lock, ref lockTaken);
    try
    {
        _waitTimes[i] = DateTime.Now;
        // Condition Variable ะฟะฐั‚ั‚ะตั€ะฝ. ะžัะฒะพะฑะพะถะดะฐะตะผ ะปะพะบ, ะตัะปะธ ะฝะต ะฒั‹ะฟะพะปะฝะตะฝะฝะพ 
        // ัะปะพะถะฝะพะต ัƒัะปะพะฒะธะต. ะ˜ ะถะดะตะผ ะฟะพะบะฐ ะบั‚ะพ-ะฝะธะฑัƒะดัŒ ัะดะตะปะฐะตั‚ Pulse / PulseAll.
        while (!CanIEat(i))
            Monitor.Wait(_lock); 
        forks[Left(i)] = i + 1;
        forks[Right(i)] = i + 1;
        _waitTimes[i] = null;
    }
    finally
    {
        if (lockTaken) Monitor.Exit(_lock);
    }
}

void PutForks(int i)
{
    // ะขะพ ะถะต ัะฐะผะพะต: lock (_lock) {..}.
    bool lockTaken = false;
    Monitor.Enter(_lock, ref lockTaken);
    try
    {
        forks[Left(i)] = 0;
        forks[Right(i)] = 0;
        // ะžัะฒะพะฑะพะดะธั‚ัŒ ะฒัะต ะฟะพั‚ะพะบะธ ะฒ ะพั‡ะตั€ะตะดะธ ะŸะžะกะ›ะ• ะฒั‹ะทะพะฒะฐ Monitor.Exit.
        Monitor.PulseAll(_lock); 
    }
    finally
    {
        if (lockTaken) Monitor.Exit(_lock);
    }
}

เช…เชนเซ€เช‚ เช…เชฎเซ‡ เชซเซ‹เชฐเซเช•เซเชธเชจเซ€ เชเช•เซเชธเซ‡เชธ เชฎเชพเชŸเซ‡ เช†เช–เชพ เชŸเซ‡เชฌเชฒเชจเซ‡ เชซเชฐเซ€เชฅเซ€ เช…เชตเชฐเซ‹เชงเชฟเชค เช•เชฐเซ€ เชฐเชนเซเชฏเชพ เช›เซ€เช, เชชเชฐเช‚เชคเซ เชนเชตเซ‡ เช…เชฎเซ‡ เชเช• เชœ เชธเชฎเชฏเซ‡ เชคเชฎเชพเชฎ เชฅเซเชฐเซ‡เชกเซ‹เชจเซ‡ เช…เชจเชพเชตเชฐเซ‹เชงเชฟเชค เช•เชฐเซ€ เชฐเชนเซเชฏเชพ เช›เซ€เช, เช…เชจเซ‡ เชœเซเชฏเชพเชฐเซ‡ เช•เซ‹เชˆ เช–เชพเชตเซเช‚ เชธเชฎเชพเชชเซเชค เช•เชฐเซ‡ เชคเซเชฏเชพเชฐเซ‡ เชชเชกเซ‹เชถเซ€เช“เชจเซ‡ เชจเชนเซ€เช‚. เชคเซ‡. เชชเซเชฐเชฅเชฎ, เช•เซ‹เชˆ เชตเซเชฏเช•เซเชคเชฟ เชชเชกเซ‹เชถเซ€เช“เชจเซ‡ เช–เชพเชฏ เช›เซ‡ เช…เชจเซ‡ เช…เชตเชฐเซ‹เชงเซ‡ เช›เซ‡, เช…เชจเซ‡ เชœเซเชฏเชพเชฐเซ‡ เช•เซ‹เชˆ เช† เชธเชฎเชพเชชเซเชค เช•เชฐเซ‡ เช›เซ‡, เชชเชฐเช‚เชคเซ เชคเชฐเชค เชœ เชซเชฐเซ€เชฅเซ€ เช–เชพเชตเชพ เชฎเชพเช‚เช—เซ‡ เช›เซ‡, เชคเซเชฏเชพเชฐเซ‡ เชคเซ‡ เชฌเซเชฒเซ‹เช•เชฟเช‚เช—เชฎเชพเช‚ เชœเชพเชฏ เช›เซ‡ เช…เชจเซ‡ เชคเซ‡เชจเชพ เชชเชกเซ‹เชถเซ€เช“เชจเซ‡ เชœเช—เชพเชกเซ‡ เช›เซ‡, เช•เชพเชฐเชฃ เช•เซ‡. เชคเซ‡เชจเซ€ เชฐเชพเชน เชœเซ‹เชตเชพเชจเซ‹ เชธเชฎเชฏ เช“เช›เซ‹ เช›เซ‡.

เช† เชฐเซ€เชคเซ‡ เช†เชชเชฃเซ‡ เชฎเชกเชพเช—เชพเช‚เช  เช…เชจเซ‡ เช•เซ‡เชŸเชฒเชพเช• เชซเชฟเชฒเชธเซ‚เชซเชจเซ€ เชญเซ‚เช–เชฎเชฐเซ‹ เชŸเชพเชณเซ€เช เช›เซ€เช. เช…เชฎเซ‡ เชŸเซ‚เช‚เช•เชพ เชฐเชพเชน เชฎเชพเชŸเซ‡ เชฒเซ‚เชชเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เช เช›เซ€เช เช…เชจเซ‡ เชฒเชพเช‚เชฌเชพ เชธเชฎเชฏ เชฎเชพเชŸเซ‡ เชฅเซเชฐเซ‡เชกเชจเซ‡ เช…เชตเชฐเซ‹เชงเชฟเชค เช•เชฐเซ€เช เช›เซ€เช. เชฆเชฐเซ‡เช•เชจเซ‡ เชเช•เชธเชพเชฅเซ‡ เช…เชจเชพเชตเชฐเซ‹เชงเชฟเชค เช•เชฐเชตเชพเชจเซเช‚ เชงเซ€เชฎเชพ เช›เซ‡ เชœเซ‹ เชฎเชพเชคเซเชฐ เชชเชพเชกเซ‹เชถเซ€เชจเซ‡ เช…เชจเชพเชตเชฐเซ‹เชงเชฟเชค เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซเช‚ เชนเซ‹เชฏ, เชœเซ‡เชฎ เช•เซ‡ เชธเชพเชฅเซ‡เชจเชพ เช‰เช•เซ‡เชฒเชฎเชพเช‚ AutoResetEvent, เชชเชฐเช‚เชคเซ เชคเชซเชพเชตเชค เชฎเซ‹เชŸเซ‹ เชจ เชนเซ‹เชตเซ‹ เชœเซ‹เชˆเช, เช•เชพเชฐเชฃ เช•เซ‡ เชฅเซเชฐเซ‡เชกเซ‹ เชชเชนเซ‡เชฒเชพ เชฏเซเชเชฐ เชฎเซ‹เชกเชฎเชพเช‚ เชฐเชนเซ‡เชตเซเช‚ เชœเซ‹เชˆเช.

ะฃ lock เชธเชฟเชจเซเชŸเซ‡เช•เซเชธเชฎเชพเช‚ เชฌเซ€เชญเชคเซเชธ เช†เชถเซเชšเชฐเซเชฏ เช›เซ‡. เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชจเซ€ เชญเชฒเชพเชฎเชฃ เช•เชฐเซ‹ Monitor เชธเซ€เชงเซเช‚ [เชฐเชฟเช•เซเชŸเชฐ] [เชเชฐเชฟเช• เชฒเชฟเชชเชฐเซเชŸ]. เชคเซ‡เชฎเชพเช‚เชฅเซ€ เชเช• เช›เซ‡ lock เชนเช‚เชฎเซ‡เชถเชพ เชฌเชนเชพเชฐ Monitor, เชœเซ‹ เชคเซเชฏเชพเช‚ เช…เชชเชตเชพเชฆ เชนเซ‹เชฏ เชคเซ‹ เชชเชฃ, เชœเซ‡ เช•เชฟเชธเซเชธเชพเชฎเชพเช‚ เช…เชจเซเชฏ เชฅเซเชฐเซ‡เชก เชถเซ‡เชฐ เช•เชฐเซ‡เชฒ เชฎเซ‡เชฎเชฐเซ€ เชธเซเชฅเชฟเชคเชฟเชจเซ‡ เชฌเชฆเชฒเซ€ เชถเช•เซ‡ เช›เซ‡. เช†เชตเชพ เช•เชฟเชธเซเชธเชพเช“เชฎเชพเช‚, เชกเซ‡เชกเชฒเซ‹เช•เชฎเชพเช‚ เชœเชตเซเช‚ เช…เชฅเชตเชพ เช•เซ‹เชˆเช• เชฐเซ€เชคเซ‡ เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎเชจเซ‡ เชธเซเชฐเช•เซเชทเชฟเชค เชฐเซ€เชคเซ‡ เชธเชฎเชพเชชเซเชค เช•เชฐเชตเซเช‚ เชตเชงเซ เชธเชพเชฐเซเช‚ เช›เซ‡. เชฌเซ€เชœเซเช‚ เช†เชถเซเชšเชฐเซเชฏ เช เช›เซ‡ เช•เซ‡ เชฎเซ‹เชจเชฟเชŸเชฐ เชธเชฟเช‚เช•เซเชฐเชจเชพเช‡เชเซ‡เชถเชจ เชฌเซเชฒเซ‹เช•เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‡ เช›เซ‡ (SyncBlock), เชœเซ‡ เชคเชฎเชพเชฎ เชชเชฆเชพเชฐเซเชฅเซ‹เชฎเชพเช‚ เชนเชพเชœเชฐ เช›เซ‡. เชคเซ‡เชฅเซ€, เชœเซ‹ เช•เซ‹เชˆ เช…เชฏเซ‹เช—เซเชฏ เช‘เชฌเซเชœเซ‡เช•เซเชŸ เชชเชธเช‚เชฆ เช•เชฐเซ‡เชฒ เชนเซ‹เชฏ, เชคเซ‹ เชคเชฎเซ‡ เชธเชฐเชณเชคเชพเชฅเซ€ เชกเซ‡เชกเชฒเซ‹เช• เชฎเซ‡เชณเชตเซ€ เชถเช•เซ‹ เช›เซ‹ (เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เชœเซ‹ เชคเชฎเซ‡ เช†เช‚เชคเชฐเชฟเช• เชธเซเชŸเซเชฐเชฟเช‚เช— เชชเชฐ เชฒเซ‰เช• เช•เชฐเซ‹ เช›เซ‹). เช…เชฎเซ‡ เช† เชฎเชพเชŸเซ‡ เชนเช‚เชฎเซ‡เชถเชพ เช›เซเชชเชพเชฏเซ‡เชฒเชพ เชชเชฆเชพเชฐเซเชฅเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เช เช›เซ€เช.

เช•เชจเซเชกเชฟเชถเชจ เชตเซ‡เชฐเชฟเชเชฌเชฒ เชชเซ‡เชŸเชฐเซเชจ เชคเชฎเชจเซ‡ เช•เซ‡เชŸเชฒเซ€เช• เชœเชŸเชฟเชฒ เชธเซเชฅเชฟเชคเชฟเชจเซ€ เช…เชชเซ‡เช•เซเชทเชพเชจเซ‡ เชตเชงเซ เชธเช‚เช•เซเชทเชฟเชชเซเชคเชฎเชพเช‚ เช…เชฎเชฒเชฎเชพเช‚ เชฎเซ‚เช•เชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡. .NET เชฎเชพเช‚, เชคเซ‡ เช…เชงเซ‚เชฐเซเช‚ เช›เซ‡, เชฎเชพเชฐเชพ เชฎเชคเซ‡, เช•เชพเชฐเชฃ เช•เซ‡ เชธเซˆเชฆเซเชงเชพเช‚เชคเชฟเช• เชฐเซ€เชคเซ‡, เช˜เชฃเชพ เชตเซ‡เชฐเชฟเชฏเซ‡เชฌเชฒเซเชธ เชชเชฐ เช˜เชฃเซ€ เช•เชคเชพเชฐ เชนเซ‹เชตเซ€ เชœเซ‹เชˆเช (เชœเซ‡เชฎ เช•เซ‡ เชชเซ‹เชธเชฟเช•เซเชธ เชฅเซเชฐเซ‡เชกเซ‹เชฎเชพเช‚), เช…เชจเซ‡ เชเช• เชฒเซ‹เช• เชชเชฐ เชจเชนเซ€เช‚. เชชเช›เซ€ เช•เซ‹เชˆ เชคเซ‡เชฎเชจเซ‡ เชฌเชงเชพ เชซเชฟเชฒเชธเซ‚เชซเซ‹ เชฎเชพเชŸเซ‡ เชฌเชจเชพเชตเซ€ เชถเช•เซ‡ เช›เซ‡. เชชเชฐเช‚เชคเซ เช† เชซเซ‹เชฐเซเชฎเชฎเชพเช‚ เชชเชฃ, เชคเซ‡ เชคเชฎเชจเซ‡ เช•เซ‹เชก เช˜เชŸเชพเชกเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡.

เช˜เชฃเชพ เชซเชฟเชฒเชธเซ‚เชซเซ‹ เช…เชฅเชตเชพ async / await

เช เซ€เช• เช›เซ‡, เชนเชตเซ‡ เช†เชชเชฃเซ‡ เชฅเซเชฐเซ‡เชกเซ‹เชจเซ‡ เช…เชธเชฐเช•เชพเชฐเช• เชฐเซ€เชคเซ‡ เชฌเซเชฒเซ‹เช• เช•เชฐเซ€ เชถเช•เซ€เช เช›เซ€เช. เชชเชฐเช‚เชคเซ เชœเซ‹ เช†เชชเชฃเซ€ เชชเชพเชธเซ‡ เช˜เชฃเชพ เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเซ‹ เชนเซ‹เชฏ เชคเซ‹? 100? 10000? เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เช…เชฎเชจเซ‡ เชตเซ‡เชฌ เชธเชฐเซเชตเชฐ เชชเชฐ 100000 เชตเชฟเชจเช‚เชคเซ€เช“ เชฎเชณเซ€ เช›เซ‡. เชฆเชฐเซ‡เช• เชตเชฟเชจเช‚เชคเซ€ เชฎเชพเชŸเซ‡ เชฅเซเชฐเซ‡เชก เชฌเชจเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เชคเซ‡ เช“เชตเชฐเชนเซ‡เชก เชนเชถเซ‡, เช•เชพเชฐเชฃ เช•เซ‡ เช˜เชฃเชพ เชฅเซเชฐเซ‡เชกเซ‹ เชธเชฎเชพเช‚เชคเชฐ เชšเชพเชฒเชถเซ‡ เชจเชนเซ€เช‚. เชฒเซ‹เชœเชฟเช•เชฒ เช•เซ‹เชฐเซ‹ เช›เซ‡ เชคเซ‡เชŸเชฒเชพ เชœ เชšเชพเชฒเชถเซ‡ (เชฎเชพเชฐเซ€ เชชเชพเชธเซ‡ 4 เช›เซ‡). เช…เชจเซ‡ เชฌเชพเช•เซ€เชจเชพ เชฌเชงเชพ เชœ เชธเช‚เชธเชพเชงเชจเซ‹ เช›เซ€เชจเชตเซ€ เชฒเซ‡เชถเซ‡. เช† เชธเชฎเชธเซเชฏเชพเชจเซ‹ เชเช• เช‰เช•เซ‡เชฒ เช async / await เชชเซ‡เชŸเชฐเซเชจ เช›เซ‡. เชคเซ‡เชจเซ‹ เชตเชฟเชšเชพเชฐ เช เช›เซ‡ เช•เซ‡ เช•เชพเชฐเซเชฏ เชฅเซเชฐเซ‡เชกเชจเซ‡ เชชเช•เชกเซ€ เชฐเชพเช–เชคเซเช‚ เชจเชฅเซ€ เชœเซ‹ เชคเซ‡เชจเซ‡ เช•เช‚เชˆเช• เชšเชพเชฒเซ เชฐเชพเช–เชตเชพ เชฎเชพเชŸเซ‡ เชฐเชพเชน เชœเซ‹เชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชนเซ‹เชฏ. เช…เชจเซ‡ เชœเซเชฏเชพเชฐเซ‡ เชคเซ‡ เช•เช‚เชˆเช• เช•เชฐเซ‡ เช›เซ‡, เชคเซเชฏเชพเชฐเซ‡ เชคเซ‡ เชคเซ‡เชจเชพ เช…เชฎเชฒเชจเซ‡ เชซเชฐเซ€เชฅเซ€ เชถเชฐเซ‚ เช•เชฐเซ‡ เช›เซ‡ (เชชเชฐเช‚เชคเซ เชคเซ‡ เชœ เชฅเซเชฐเซ‡เชก เชชเชฐ เชœเชฐเซ‚เชฐเซ€ เชจเชฅเซ€!). เช…เชฎเชพเชฐเชพ เช•เชฟเชธเซเชธเชพเชฎเชพเช‚, เช…เชฎเซ‡ เช•เชพเช‚เชŸเซ‹ เชฎเชพเชŸเซ‡ เชฐเชพเชน เชœเซ‹เชˆเชถเซเช‚.

SemaphoreSlim เช† เชฎเชพเชŸเซ‡ เช›เซ‡ WaitAsync() เชชเชฆเซเชงเชคเชฟ เช…เชนเซ€เช‚ เช† เชชเซ‡เชŸเชฐเซเชจเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เช…เชฎเชฒเซ€เช•เชฐเชฃ เช›เซ‡.

// ะ—ะฐะฟัƒัะบ ั‚ะฐะบะพะน ะถะต, ะบะฐะบ ั€ะฐะฝัŒัˆะต. ะ“ะดะต-ะฝะธะฑัƒะดัŒ ะฒ ะฟั€ะพะณั€ะฐะผะผะต:
Task.Run(() => Run(i, cancelTokenSource.Token));

// ะ—ะฐะฟัƒัะบ ั„ะธะปะพัะพั„ะฐ.
// ะšะปัŽั‡ะตะฒะพะต ัะปะพะฒะพ async -- ะบะพะผะฟะธะปัั‚ะพั€ ั‚ั€ะฐะฝัะปะธั€ัƒะตั‚ ัั‚ะพั‚ ะผะตั‚ะพั‚ ะฒ ะฐัะธะฝั…ั€ะพะฝะฝั‹ะน.
public async Task Run(int i, CancellationToken token)
{
    while (true)
    {
        // await -- ะฑัƒะดะตะผ ะพะถะธะดะฐั‚ัŒ ะบะฐะบะพะณะพ-ั‚ะพ ัะพะฑั‹ั‚ะธั.
        await TakeForks(i);
        // ะŸะพัะปะต await, ะฟั€ะพะดะพะปะถะตะฝะธะต ะฒะพะทะผะพะถะฝะพ ะฒ ะดั€ัƒะณะพะผ ะฟะพั‚ะพะบะต.
        eatenFood[i] = (eatenFood[i] + 1) % (int.MaxValue - 1);
        // ะœะพะถะตั‚ ะฑั‹ั‚ัŒ ะฝะตัะบะพะปัŒะบะพ ัะพะฑั‹ั‚ะธะน ะดะปั ะพะถะธะดะฐะฝะธั.
        await PutForks(i);

        Think(i);

        if (token.IsCancellationRequested) break;
    }
}

async Task TakeForks(int i)
{
    bool hasForks = false;
    while (!hasForks)
    {
        // ะ’ะทะฐะธะผะพะธัะบะปัŽั‡ะฐัŽั‰ะธะน ะดะพัั‚ัƒะฟ ะบ ัั‚ะพะปัƒ:
        await _tableSemaphore.WaitAsync();
        if (forks[Left(i)] == 0 && forks[Right(i)] == 0)
        {
            forks[Left(i)] = i+1;
            forks[Right(i)] = i+1;
            hasForks = true;
        }
        _tableSemaphore.Release();
        // ะ‘ัƒะดะตะผ ะพะถะธะดะฐั‚ัŒ, ั‡ั‚ะพะฑั‹ ัะพัะตะด ะฟะพะปะพะถะธะป ะฒะธะปะบะธ:
        if (!hasForks)
            await _philosopherSemaphores[i].WaitAsync();
    }
}

// ะ–ะดะตะผ ะดะพัั‚ัƒะฟะฐ ะบ ัั‚ะพะปัƒ ะธ ะบะปะฐะดะตะผ ะฒะธะปะบะธ.
async Task PutForks(int i)
{
    await _tableSemaphore.WaitAsync();
    forks[Left(i)] = 0;
    // "ะŸั€ะพะฑัƒะดะธั‚ัŒ" ัะพัะตะดะตะน, ะตัะปะธ ะพะฝะธ "ัะฟะฐะปะธ".
    _philosopherSemaphores[LeftPhilosopher(i)].Release();
    forks[Right(i)] = 0;
    _philosopherSemaphores[RightPhilosopher(i)].Release();
    _tableSemaphore.Release();
}

เชธเชพเชฅเซ‡ เชชเชฆเซเชงเชคเชฟ async / await เชเช• เชฎเซเชถเซเช•เซ‡เชฒ เชฐเชพเชœเซเชฏ เชฎเชถเซ€เชจเชฎเชพเช‚ เช…เชจเซเชตเชพเชฆเชฟเชค เชฅเชพเชฏ เช›เซ‡ เชœเซ‡ เชคเชฐเชค เชœ เชคเซ‡เชจเซ€ เช†เช‚เชคเชฐเชฟเช• เชชเชฐเชค เช•เชฐเซ‡ เช›เซ‡ Task. เชคเซ‡เชจเชพ เชฆเซเชตเชพเชฐเชพ, เชคเชฎเซ‡ เชชเชฆเซเชงเชคเชฟ เชชเซ‚เชฐเซเชฃ เชฅเชตเชพเชจเซ€ เชฐเชพเชน เชœเซ‹เชˆ เชถเช•เซ‹ เช›เซ‹, เชคเซ‡เชจเซ‡ เชฐเชฆ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹ เช…เชจเซ‡ เชฌเชพเช•เซ€เชจเซเช‚ เชฌเชงเซเช‚ เชœเซ‡ เชคเชฎเซ‡ เช•เชพเชฐเซเชฏ เชธเชพเชฅเซ‡ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹. เชชเชฆเซเชงเชคเชฟเชจเซ€ เช…เช‚เชฆเชฐ, เชฐเชพเชœเซเชฏ เชฎเชถเซ€เชจ เช…เชฎเชฒเชจเซ‡ เชจเชฟเชฏเช‚เชคเซเชฐเชฟเชค เช•เชฐเซ‡ เช›เซ‡. เชฌเซ‹เชŸเชฎ เชฒเชพเช‡เชจ เช เช›เซ‡ เช•เซ‡ เชœเซ‹ เชคเซเชฏเชพเช‚ เช•เซ‹เชˆ เชตเชฟเชฒเช‚เชฌ เชจ เชนเซ‹เชฏ, เชคเซ‹ เช…เชฎเชฒ เชธเชฟเช‚เช•เซเชฐเชจเชธ เช›เซ‡, เช…เชจเซ‡ เชœเซ‹ เชคเซเชฏเชพเช‚ เช›เซ‡, เชคเซ‹ เชชเช›เซ€ เชฅเซเชฐเซ‡เชก เชชเซเชฐเช•เชพเชถเชฟเชค เชฅเชพเชฏ เช›เซ‡. เช†เชจเซ‡ เชตเชงเซ เชธเชพเชฐเซ€ เชฐเซ€เชคเซ‡ เชธเชฎเชœเชตเชพ เชฎเชพเชŸเซ‡, เช† เชฐเชพเชœเซเชฏ เชฎเชถเซ€เชจเชจเซ‡ เชœเซ‹เชตเซเช‚ เชตเชงเซ เชธเชพเชฐเซเช‚ เช›เซ‡. เชคเชฎเซ‡ เช†เชฎเชพเช‚เชฅเซ€ เชธเชพเช‚เช•เชณเซ‹ เชฌเชจเชพเชตเซ€ เชถเช•เซ‹ เช›เซ‹ async / await เชชเชฆเซเชงเชคเชฟเช“

เชšเชพเชฒเซ‹ เชชเชฐเซ€เช•เซเชทเชฃ เช•เชฐเซ€เช. 100 เชฒเซ‹เชœเชฟเช•เชฒ เช•เซ‹เชฐเซ‹, 4 เชธเซ‡เช•เชจเซเชก เชธเชพเชฅเซ‡ เชฎเชถเซ€เชจ เชชเชฐ 8 เชซเชฟเชฒเซ‹เชธเซ‹เชซเชฐเชจเซเช‚ เช•เชพเชฎ. เชฎเซ‹เชจเชฟเชŸเชฐ เชธเชพเชฅเซ‡เชจเซเช‚ เชชเชพเช›เชฒเซเช‚ เชธเซ‹เชฒเซเชฏเซเชถเชจ เชซเช•เซเชค เชชเซเชฐเชฅเชฎ 4 เชฅเซเชฐเซ‡เชกเซ‹ เชšเชฒเชพเชตเชคเซเช‚ เชนเชคเซเช‚ เช…เชจเซ‡ เชฌเชพเช•เซ€เชจเซเช‚ เชฌเชฟเชฒเช•เซเชฒ เชšเชพเชฒเชคเซเช‚ เชจเชฅเซ€. เช† 4 เชฅเซเชฐเซ‡เชกเซ‹เชฎเชพเช‚เชฅเซ€ เชฆเชฐเซ‡เช• เชฒเช—เชญเช— 2ms เชฎเชพเชŸเซ‡ เชจเชฟเชทเซเช•เซเชฐเชฟเชฏ เชนเชคเซ‹. เช…เชจเซ‡ async/await เชธเซ‹เชฒเซเชฏเซเชถเชจ เชฆเชฐเซ‡เช• 100 เชธเซ‡เช•เชจเซเชกเชจเซ€ เชธเชฐเซ‡เชฐเชพเชถ เชชเซเชฐเชคเซ€เช•เซเชทเชพ เชธเชพเชฅเซ‡, เชคเชฎเชพเชฎ 6.8 เชฐเชจ เช•เชฐเซ‡ เช›เซ‡. เช…เชฒเชฌเชคเซเชค, เชตเชพเชธเซเชคเชตเชฟเช• เชธเชฟเชธเซเชŸเชฎเซ‹เชฎเชพเช‚, 6 เชธเซ‡เช•เชจเซเชก เชฎเชพเชŸเซ‡ เชจเชฟเชทเซเช•เซเชฐเชฟเชฏ เช…เชธเซเชตเซ€เช•เชพเชฐเซเชฏ เช›เซ‡ เช…เชจเซ‡ เช†เชจเชพ เชœเซ‡เชตเซ€ เช˜เชฃเซ€ เชตเชฟเชจเช‚เชคเซ€เช“ เชชเชฐ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพ เชจ เช•เชฐเชตเซ€ เชคเซ‡ เชตเชงเซ เชธเชพเชฐเซเช‚ เช›เซ‡. เชฎเซ‹เชจเชฟเชŸเชฐ เชธเชพเชฅเซ‡เชจเซเช‚ เชธเซ‹เชฒเซเชฏเซเชถเชจ เชฌเชฟเชฒเช•เซเชฒ เชฎเชพเชชเซ€ เชถเช•เชพเชฏ เชคเซ‡เชตเซเช‚ เชจเชฅเซ€.

เชจเชฟเชทเซเช•เชฐเซเชท

เชœเซ‡เชฎ เชคเชฎเซ‡ เช† เชจเชพเชจเชพ เช‰เชฆเชพเชนเชฐเชฃเซ‹เชฎเชพเช‚เชฅเซ€ เชœเซ‹เชˆ เชถเช•เซ‹ เช›เซ‹, .NET เช˜เชฃเชพ เชธเชฟเช‚เช•เซเชฐเซ‹เชจเชพเช‡เชเซ‡เชถเชจ เช•เชจเซเชธเซเชŸเซเชฐเช•เซเชŸเซเชธเชจเซ‡ เชธเชชเซ‹เชฐเซเชŸ เช•เชฐเซ‡ เช›เซ‡. เชœเซ‹ เช•เซ‡, เชคเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชฐเชตเซ‹ เชคเซ‡ เชนเช‚เชฎเซ‡เชถเชพ เชธเซเชชเชทเซเชŸ เชนเซ‹เชคเซเช‚ เชจเชฅเซ€. เชฎเชจเซ‡ เช†เชถเชพ เช›เซ‡ เช•เซ‡ เช† เชฒเซ‡เช– เชฎเชฆเชฆเชฐเซ‚เชช เชนเชคเซ‹. เชนเชฎเชฃเชพเช‚ เชฎเชพเชŸเซ‡, เช† เช…เช‚เชค เช›เซ‡, เชชเชฐเช‚เชคเซ เชนเชœเซ€ เช˜เชฃเซ€ เชฐเชธเชชเซเชฐเชฆ เชตเชธเซเชคเซเช“ เชฌเชพเช•เซ€ เช›เซ‡, เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เชฅเซเชฐเซ‡เชก-เชธเซ‡เชซ เช•เชฒเซ‡เช•เซเชถเชจ, TPL เชกเซ‡เชŸเชพเชซเซเชฒเซ‹, เชฐเชฟเชเช•เซเชŸเชฟเชต เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎเชฟเช‚เช—, เชธเซ‰เชซเซเชŸเชตเซ‡เชฐ เชŸเซเชฐเชพเชจเซเชเซ‡เช•เซเชถเชจ เชฎเซ‹เชกเชฒ, เชตเช—เซ‡เชฐเซ‡.

เชธเซเชคเซเชฐเซ‹เชคเซ‹

เชธเซ‹เชฐเซเชธ: www.habr.com

เชเช• เชŸเชฟเชชเซเชชเชฃเซ€ เช‰เชฎเซ‡เชฐเซ‹