Well-Fed Philosophers ឬ Competitive .NET Programming

Well-Fed Philosophers ឬ Competitive .NET Programming

αžŸαžΌαž˜αž€αŸ’αžšαž‘αŸαž€αž˜αžΎαž›αž–αžΈαžšαž”αŸ€αž”αžŠαŸ‚αž›αž€αž˜αŸ’αž˜αžœαž·αž’αžΈαžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆ αž“αž·αž„αž”αŸ‰αžΆαžšαŸ‰αžΆαž‘αŸ‚αž›αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž“αŸ…αž€αŸ’αž“αž»αž„ .Net αžŠαŸ„αž™αž”αŸ’αžšαžΎαž§αž‘αžΆαž αžšαžŽαŸαž“αŸƒαž”αž‰αŸ’αž αžΆαž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌαž’αžΆαž αžΆαžšαžαŸ’αž„αŸƒαžαŸ’αžšαž„αŸ‹αŸ” αž•αŸ‚αž“αž€αžΆαžšαž“αŸαŸ‡αž˜αžΆαž“αžŠαžΌαž…αžαžΆαž„αž€αŸ’αžšαŸ„αž˜ αž–αžΈαž€αžΆαžšαž’αŸ’αžœαžΎαžŸαž˜αž€αžΆαž›αž€αž˜αŸ’αž˜αžαŸ’αžŸαŸ‚αžŸαŸ’αžšαž‘αžΆαž™/αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž‘αŸ…αž‚αŸ†αžšαžΌαžαž½αžŸαž˜αŸ’αžαŸ‚αž„ (αž€αŸ’αž“αž»αž„αž•αŸ’αž“αŸ‚αž€αžαžΆαž„αž€αŸ’αžšαŸ„αž˜)αŸ” αž’αžαŸ’αžαž”αž‘αž’αžΆαž…αž˜αžΆαž“αž”αŸ’αžšαž™αŸ„αž‡αž“αŸαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž’αŸ’αž“αž€αžŸαŸ’αž‚αžΆαž›αŸ‹αž‚αŸ’αž“αžΆαžŠαŸ†αž”αžΌαž„ αž¬αžŠαžΎαž˜αŸ’αž”αžΈαž’αŸ’αžœαžΎαž±αŸ’αž™αž…αŸ†αžŽαŸαŸ‡αžŠαžΉαž„αžšαž”αžŸαŸ‹αž’αŸ’αž“αž€αž‘αžΎαž„αžœαž·αž‰αŸ”

αž αŸαžαž»αž’αŸ’αžœαžΈαž€αŸαž…αŸαŸ‡αž’αŸ’αžœαžΎαž”αŸ‚αž”αž“αŸαŸ‡? αžαŸ’αžšαž„αŸ‹αžŸαŸŠαžΈαžŸαŸ’αž‘αŸαžšαž€αŸ†αž–αž»αž„αžˆαžΆαž“αžŠαž›αŸ‹αž‘αŸ†αž αŸ†αž’αž”αŸ’αž”αž”αžšαž˜αžΆαžšαž”αžŸαŸ‹αž–αž½αž€αž‚αŸ αž…αŸ’αž”αžΆαž”αŸ‹αžšαž”αžŸαŸ‹ Moore αž€αŸ†αž–αž»αž„αžˆαžΆαž“αžŠαž›αŸ‹αž€αž˜αŸ’αžšαž·αžαž“αŸƒαž›αŸ’αž”αžΏαž“αž–αž“αŸ’αž›αžΊ αž αžΎαž™αžŠαžΌαž…αŸ’αž“αŸαŸ‡αž€αžΆαžšαžšαžΈαž€αž…αž˜αŸ’αžšαžΎαž“αžαŸ’αžšαžΌαžœαž”αžΆαž“αž‚αŸαžŸαž„αŸ’αž€αŸαžαžƒαžΎαž‰αž‡αžΆαž…αŸ†αž“αž½αž“ αžαŸ’αžšαž„αŸ‹αžŸαŸŠαžΈαžŸαŸ’αž‘αŸαžšαž€αžΆαž“αŸ‹αžαŸ‚αž…αŸ’αžšαžΎαž“αž’αžΆαž…αžαŸ’αžšαžΌαžœαž”αžΆαž“αž’αŸ’αžœαžΎαž‘αžΎαž„αŸ” αž‘αž“αŸ’αž‘αžΉαž˜αž“αžΉαž„αž“αŸαŸ‡αž”αžšαž·αž˜αžΆαžŽαž‘αž·αž“αŸ’αž“αž“αŸαž™αž€αŸ†αž–αž»αž„αž€αžΎαž“αž‘αžΎαž„ αž αžΎαž™αž’αŸ’αž“αž€αž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αžšαŸ†αž–αžΉαž„αžαžΆαž“αžΉαž„αž˜αžΆαž“αž€αžΆαžšαž†αŸ’αž›αžΎαž™αžαž”αž—αŸ’αž›αžΆαž˜αŸ—αž–αžΈαž”αŸ’αžšαž–αŸαž“αŸ’αž’αŸ” αž€αŸ’αž“αž»αž„β€‹αžŸαŸ’αžαžΆαž“αž—αžΆαž–β€‹αž”αŸ‚αž”β€‹αž“αŸαŸ‡ αž€αžΆαžšβ€‹αžŸαžšαžŸαŸαžšβ€‹αž€αž˜αŸ’αž˜αžœαž·αž’αžΈ "αž’αž˜αŸ’αž˜αžαžΆ" αž“αŸ…β€‹αž–αŸαž›β€‹αžŠαŸ‚αž›β€‹αž™αžΎαž„β€‹αž˜αžΆαž“β€‹αžαŸ’αžŸαŸ‚β€‹αžŸαŸ’αžšαž‘αžΆαž™β€‹αž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·β€‹αž˜αž½αž™ αž˜αž·αž“β€‹αž˜αžΆαž“β€‹αž”αŸ’αžšαžŸαž·αž‘αŸ’αž’αž—αžΆαž–β€‹αž‘αŸ€αžβ€‹αž‘αŸαŸ” αž™αžΎαž„αžαŸ’αžšαžΌαžœαžŠαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αž”αž‰αŸ’αž αžΆαž“αŸƒαž€αžΆαžšαž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž€αŸ’αž“αž»αž„αž–αŸαž›αžŠαŸ†αžŽαžΆαž›αž‚αŸ’αž“αžΆ αž¬αžŸαŸ’αžšαž”αž‚αŸ’αž“αžΆαŸ” αž›αžΎαžŸαž–αžΈαž“αŸαŸ‡αž‘αŸ…αž‘αŸ€αžαž”αž‰αŸ’αž αžΆαž“αŸαŸ‡αž˜αžΆαž“αž“αŸ…αž€αž˜αŸ’αžšαž·αžαž•αŸ’αžŸαŸαž„αŸ—αž‚αŸ’αž“αžΆ: αž“αŸ…αž€αž˜αŸ’αžšαž·αžαžαŸ’αžŸαŸ‚αžŸαŸ’αžšαž‘αžΆαž™αž“αŸ…αž€αž˜αŸ’αžšαž·αžαžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž“αŸ…αž€αž˜αŸ’αžšαž·αžαž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αž“αŸ…αž›αžΎαž”αžŽαŸ’αžαžΆαž‰ (αž”αŸ’αžšαž–αŸαž“αŸ’αž’αž…αŸ‚αž€αž…αžΆαž™) αŸ” .NET αž˜αžΆαž“αž”αž…αŸ’αž…αŸαž€αžœαž·αž‘αŸ’αž™αžΆαžŠαŸ‚αž›αž˜αžΆαž“αž‚αž»αžŽαž—αžΆαž–αžαŸ’αž–αžŸαŸ‹ αžŸαžΆαž€αž›αŸ’αž”αž„αž–αŸαž›αžœαŸαž›αžΆ αžŠαžΎαž˜αŸ’αž”αžΈαžŠαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αž”αž‰αŸ’αž αžΆαž‘αžΆαŸ†αž„αž“αŸ„αŸ‡αž”αžΆαž“αž™αŸ‰αžΆαž„αž†αžΆαž”αŸ‹αžšαž αŸαžŸ αž“αž·αž„αž”αŸ’αžšαž€αž”αžŠαŸ„αž™αž”αŸ’αžšαžŸαž·αž‘αŸ’αž’αž—αžΆαž–αŸ”

αž‚αŸ„αž›αž”αŸ†αžŽαž„

Edsger Dijkstra αž”αžΆαž“αžŸαž½αžšαž”αž‰αŸ’αž αžΆαž“αŸαŸ‡αžŠαž›αŸ‹αžŸαž·αžŸαŸ’αžŸαžšαž”αžŸαŸ‹αž‚αžΆαžαŸ‹αž€αžΆαž›αž–αžΈαž†αŸ’αž“αžΆαŸ† 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αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž‡αžΆαž˜αž½αž™αž“αžΉαž„αž—αžΆαž–αž„αžΆαž™αžŸαŸ’αžšαž½αž›αž‚αŸ’αžšαž”αŸ‹αž”αŸ‚αž”αž™αŸ‰αžΆαž„αŸ– αžŸαž˜αžαŸ’αžαž—αžΆαž–αž€αŸ’αž“αž»αž„αž€αžΆαžšαž…αžΆαž”αŸ‹αž•αŸ’αžαžΎαž˜αž€αž·αž…αŸ’αž…αž€αžΆαžšαž˜αž½αž™αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž–αžΈαž€αž·αž…αŸ’αž…αž€αžΆαžšαž•αŸ’αžŸαŸαž„αŸ— αž”αž‰αŸ’αž‡αžΌαž“αž–αž½αž€αž‚αŸαž˜αž€αžœαž·αž‰αž–αžΈαž˜αž»αžαž„αžΆαžš αž„αžΆαž™αžŸαŸ’αžšαž½αž›αžšαŸ†αžαžΆαž“αž–αž½αž€αž‚αŸ αž“αž·αž„αž…αŸ’αžšαžΎαž“αž‘αŸ€αžαŸ” αŸ” αž™αžΎαž„αž“αžΉαž„αž“αž·αž™αžΆαž™αž’αŸ†αž–αžΈαžšαžΏαž„αž“αŸαŸ‡αž“αŸ…αž–αŸαž›αž€αŸ’αžšαŸ„αž™αŸ”

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 αŸ”

Well-Fed Philosophers ឬ Competitive .NET Programming

αž“αŸ…αž€αŸ’αž“αž»αž„αžšαžΌαž”αž—αžΆαž–αž€αžΆαžšαž‘αž”αŸ‹αžŸαŸ’αž€αžΆαžαŸ‹αžαŸ’αžŸαŸ‚αžŸαŸ’αžšαž‘αžΆαž™ (αž‡αžΆαž”αŸ‹αž‚αžΆαŸ†αž„) αŸ” αž–αžŽαŸŒαž”αŸƒαžαž„αž”αž„αŸ’αž αžΆαž‰αž–αžΈαž€αžΆαžšαž”αŸ’αžšαžαž·αž”αžαŸ’αžαž· αž–αžŽαŸŒαž€αŸ’αžšαž αž˜αž”αž„αŸ’αž αžΆαž‰αž–αžΈαž€αžΆαžšαž’αŸ’αžœαžΎαžŸαž˜αž€αžΆαž›αž€αž˜αŸ’αž˜ αž αžΎαž™αž–αžŽαŸŒαž”αŸ’αžšαž•αŸαŸ‡αž”αž„αŸ’αž αžΆαž‰αžαžΆαžαŸ’αžŸαŸ‚αžŸαŸ’αžšαž‘αžΆαž™αž€αŸ†αž–αž»αž„αžŠαŸαž€αŸ” Diamonds αž”αž„αŸ’αž αžΆαž‰αž–αžΈαž–αŸαž›αžœαŸαž›αžΆαž…αžΆαž”αŸ‹αž•αŸ’αžαžΎαž˜αž“αŸƒ Tasks αŸ”

αž€αžΆαžšαžŸαŸ’αžšαŸαž€αžƒαŸ’αž›αžΆαž“αž“αŸƒαž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌ

αž‘αŸ„αŸ‡αž”αžΈαž‡αžΆαž’αŸ’αž“αž€αž˜αž·αž“αžαŸ’αžšαžΌαžœαž€αžΆαžšαž’αžΆαž αžΆαžšαž…αŸ’αžšαžΎαž“αžŠαžΎαž˜αŸ’αž”αžΈαž‚αž·αžαž€αŸαžŠαŸ„αž™ αž€αžΆαžšαžŸαŸ’αžšαŸαž€αžƒαŸ’αž›αžΆαž“αž’αžΆαž…αž”αž„αŸ’αžαŸ†αž“αžšαžŽαžΆαž˜αŸ’αž“αžΆαž€αŸ‹αž±αŸ’αž™αž”αŸ„αŸ‡αž”αž„αŸ‹αž‘αžŸαŸ’αžŸαž“αžœαž·αž‡αŸ’αž‡αžΆαŸ” αž…αžΌαžšαž™αžΎαž„αž–αŸ’αž™αžΆαž™αžΆαž˜αž€αŸ’αž›αŸ‚αž„αž’αŸ’αžœαžΎαžŸαŸ’αžαžΆαž“αž—αžΆαž–αž“αŸƒαž—αžΆαž–αž’αžαŸ‹αžƒαŸ’αž›αžΆαž“αžαŸ’αžŸαŸ‚αžŸαŸ’αžšαž‘αžΆαž™αž“αŸ…αž€αŸ’αž“αž»αž„αž”αž‰αŸ’αž αžΆαžšαž”αžŸαŸ‹αž™αžΎαž„αŸ” αž—αžΆαž–αž’αžαŸ‹αžƒαŸ’αž›αžΆαž“αž‚αžΊαž“αŸ…αž–αŸαž›αžŠαŸ‚αž›αž’αŸ†αž”αŸ„αŸ‡αžŠαŸ†αžŽαžΎαžšαž€αžΆαžš αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž”αžΎαž‚αŸ’αž˜αžΆαž“αž€αžΆαžšαž„αžΆαžšαžŸαŸ†αžαžΆαž“αŸ‹αž‘αŸ αž˜αŸ’αž™αŸ‰αžΆαž„αžœαž·αž‰αž‘αŸ€αž αžœαžΆαž‚αžΊαž‡αžΆαž€αžΆαžšαž‡αžΆαž”αŸ‹αž‚αžΆαŸ†αž„αžŠαžΌαž…αž‚αŸ’αž“αžΆ αž˜αžΆαž“αžαŸ‚αž–αŸαž›αž“αŸαŸ‡αžαŸ’αžŸαŸ‚αž“αŸαŸ‡αž˜αž·αž“αžŠαŸαž€αž‘αŸ αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž€αŸ†αž–αž»αž„αžŸαŸ’αžœαŸ‚αž„αžšαž€αžšαž”αžŸαŸ‹αž‰αŸ‰αžΆαŸ†αž™αŸ‰αžΆαž„αžŸαž€αž˜αŸ’αž˜ αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž˜αž·αž“αž˜αžΆαž“αž’αžΆαž αžΆαžšαŸ” αžŠαžΎαž˜αŸ’αž”αžΈαž‡αŸ€αžŸαžœαžΆαž„αž€αžΆαžšαžŸαŸ’αž‘αŸ‡αž‰αžΉαž€αž‰αžΆαž”αŸ‹ αž™αžΎαž„αž“αžΉαž„αžŠαžΆαž€αŸ‹αžŸαž˜αž˜αž€αžœαž·αž‰ αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž™αžΎαž„αž˜αž·αž“αž’αžΆαž…αž™αž€αž˜αž½αž™αž•αŸ’αžŸαŸαž„αž‘αŸ€αžαŸ”

// Π’ΠΎ ΠΆΠ΅ Ρ‡Ρ‚ΠΎ ΠΈ Π² 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 αžŠαž„αžαž·αž…αž‡αžΆαž„αž’αŸ’αž“αž€αž’αžΆαž€αŸ’αžšαž€αŸ‹αŸ” αžŠαžΌαž…αŸ’αž“αŸαŸ‡αž€αŸ†αž αž»αžŸαžαžΌαž…αž˜αž½αž™αž“αŸ…αž€αŸ’αž“αž»αž„αž€αžΌαžŠαž“αžΆαŸ†αž‘αŸ…αžšαž€αž€αžΆαžšαž’αŸ’αž›αžΆαž€αŸ‹αž…αž»αŸ‡αž“αŸƒαž€αžΆαžšαž’αž“αž»αžœαžαŸ’αžαŸ” αžαŸ’αžšαž„αŸ‹αž“αŸαŸ‡αž€αŸαž‚αž½αžšαž€αžαŸ‹αžŸαž˜αŸ’αž‚αžΆαž›αŸ‹αž•αž„αžŠαŸ‚αžšαžαžΆ αžŸαŸ’αžαžΆαž“αž—αžΆαž–αžŠαŸαž€αž˜αŸ’αžšαž˜αž½αž™αž’αžΆαž…αž€αžΎαžαž‘αžΎαž„αž“αŸ…αž–αŸαž›αžŠαŸ‚αž›αž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌαž‘αžΆαŸ†αž„αž’αžŸαŸ‹αž™αž€αžŠαŸƒαž†αŸ’αžœαŸαž„ αž’αžαŸ‹αž˜αžΆαž“αžŸαŸ’αžαžΆαŸ†αž‘αŸ αž‚αŸαžŠαžΆαž€αŸ‹αž†αŸ’αžœαŸαž„αž…αž»αŸ‡ αž…αžΆαŸ†αž™αž€αž†αŸ’αžœαŸαž„αž˜αŸ’αžαž„αž‘αŸ€αžαŸ”αž›αŸ” αžŸαŸ’αžαžΆαž“αž—αžΆαž–αž“αŸαŸ‡αž€αŸαž‡αžΆαž—αžΆαž–αž’αžαŸ‹αžƒαŸ’αž›αžΆαž“αž•αž„αžŠαŸ‚αžš αžŠαžΌαž…αž‡αžΆαž€αžΆαžšαžšαžΆαžšαžΆαŸ†αž„αž‚αŸ’αž“αžΆαž‘αŸ…αžœαž·αž‰αž‘αŸ…αž˜αž€ αžαŸ’αž‰αž»αŸ†αž˜αž·αž“αž’αžΆαž…αž’αŸ’αžœαžΎαžœαžΆαž‘αžΎαž„αžœαž·αž‰αž”αžΆαž“αž‘αŸαŸ” αžαžΆαž„αž€αŸ’αžšαŸ„αž˜αž“αŸαŸ‡αž‡αžΆαžšαžΌαž”αž—αžΆαž–αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžŸαŸ’αžαžΆαž“αž—αžΆαž–αž˜αž½αž™αžŠαŸ‚αž›αž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌαž’αžΆαž€αŸ’αžšαž€αŸ‹αž–αžΈαžšαž“αžΆαž€αŸ‹αž”αžΆαž“αž™αž€αžŠαŸƒαž‘αžΆαŸ†αž„αž–αžΈαžš αž αžΎαž™αž’αŸ’αž“αž€αž›αŸ’αž’αž–αžΈαžšαž“αžΆαž€αŸ‹αž€αŸ†αž–αž»αž„αž’αžαŸ‹αžƒαŸ’αž›αžΆαž“αŸ”

Well-Fed Philosophers ឬ Competitive .NET Programming

αž“αŸ…αž‘αžΈαž“αŸαŸ‡ αž’αŸ’αž“αž€αž’αžΆαž…αž˜αžΎαž›αžƒαžΎαž‰αžαžΆ αž–αŸαž›αžαŸ’αž›αŸ‡αžαŸ’αžŸαŸ‚αžŸαŸ’αžšαž›αžΆαž™αž—αŸ’αž‰αžΆαž€αŸ‹αž‘αžΎαž„ αž αžΎαž™αž–αŸ’αž™αžΆαž™αžΆαž˜αž™αž€αž’αž“αž’αžΆαž“αŸ” αžŸαŸ’αž“αžΌαž›αž–αžΈαžšαž€αŸ’αž“αž»αž„αž…αŸ†αžŽαŸ„αž˜αž”αž½αž“αž˜αž·αž“αž’αŸ’αžœαžΎαž’αŸ’αžœαžΈαžŸαŸ„αŸ‡ (αž€αŸ’αžšαžΆαž αŸ’αžœαž–αžŽαŸŒαž”αŸƒαžαž„αžαžΆαž„αž›αžΎ)αŸ”

αž€αžΆαžšαžŸαŸ’αž›αžΆαž”αŸ‹αžšαž”αžŸαŸ‹αž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌ

αž‡αžΆαž€αžΆαžšαž”αŸ’αžšαžŸαžΎαžšαžŽαžΆαžŸαŸ‹, αž”αž‰αŸ’αž αžΆαž˜αž½αž™αž‘αŸ€αžαžŠαŸ‚αž›αž’αžΆαž…αžšαŸ†αžαžΆαž“αžŠαž›αŸ‹αž’αžΆαž αžΆαžšαž–αŸαž›αž›αŸ’αž„αžΆαž…αžŠαŸαžšαž»αž„αžšαžΏαž„αžšαž”αžŸαŸ‹αž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌαž‚αžΊαž”αŸ’αžšαžŸαž·αž“αž”αžΎαž˜αŸ’αž“αžΆαž€αŸ‹αž€αŸ’αž“αž»αž„αž…αŸ†αžŽαŸ„αž˜αž–αž½αž€αž‚αŸαžŸαŸ’αž›αžΆαž”αŸ‹αž—αŸ’αž›αžΆαž˜αŸ—αž‡αžΆαž˜αž½αž™αž“αžΉαž„αžŸαž˜αž“αŸ…αž€αŸ’αž“αž»αž„αžŠαŸƒαžšαž”αžŸαŸ‹αž‚αžΆαžαŸ‹ (αž αžΎαž™αž‚αžΆαžαŸ‹αž“αžΉαž„αžαŸ’αžšαžΌαžœαž€αž”αŸ‹αžαžΆαž˜αžšαž”αŸ€αž”αž“αŸ„αŸ‡) αŸ” αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž˜αž€αž’αŸ’αž“αž€αž‡αž·αžαžαžΆαž„αž“αžΉαž„αžαŸ’αžšαžΌαžœαž…αžΆαž€αž…αŸαž‰αžŠαŸ„αž™αž‚αŸ’αž˜αžΆαž“αž’αžΆαž αžΆαžšαžαŸ’αž„αŸƒαžαŸ’αžšαž„αŸ‹αŸ” αž’αŸ’αž“αž€αž’αžΆαž…αž”αž„αŸ’αž€αžΎαžαž€αžΌαžŠαž§αž‘αžΆαž αžšαžŽαŸαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžšαžŽαžΈαž“αŸαŸ‡αžŠαŸ„αž™αžαŸ’αž›αž½αž“αž―αž„ αž§αž‘αžΆαž αžšαžŽαŸαžœαžΆαžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ„αŸ‡αž…αŸ„αž› NullReferenceException αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž–αžΈαž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌαž™αž€αžŸαž˜αŸ” αž αžΎαž™αžŠαŸ„αž™αžœαž·αž’αžΈαž“αŸαŸ‡ αž€αžšαžŽαžΈαž›αžΎαž€αž›αŸ‚αž„αž“αžΉαž„αž˜αž·αž“αžαŸ’αžšαžΌαžœαž”αžΆαž“αžŠαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αž‘αŸ αž αžΎαž™αž›αŸαžαž€αžΌαžŠαž αŸ…αž‘αžΌαžšαžŸαž–αŸ’αž‘αž“αžΉαž„αž˜αž·αž“αž‚αŸ’αžšαžΆαž“αŸ‹αžαŸ‚αž…αžΆαž”αŸ‹αžœαžΆαž‘αŸ (αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžšαžΏαž„αž“αŸαŸ‡ AppDomain.CurrentDomain.UnhandledException αž“αž·αž„αž›)αŸ” αžŠαžΌαž…αŸ’αž“αŸαŸ‡ αž’αŸ’αž“αž€αžŠαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αž€αŸ†αž αž»αžŸαž‚αžΊαžαŸ’αžšαžΌαžœαž€αžΆαžšαž‡αžΆαž…αžΆαŸ†αž”αžΆαž…αŸ‹αž“αŸ…αž€αŸ’αž“αž»αž„αžαŸ’αžŸαŸ‚αžŸαŸ’αžšαž‘αžΆαž™αžŠαŸ„αž™αžαŸ’αž›αž½αž“αž―αž„ αž“αž·αž„αž‡αžΆαž˜αž½αž™αž“αžΉαž„αž€αžΆαžšαž”αž‰αŸ’αž…αž”αŸ‹αž”αŸ’αžšαž€αž”αžŠαŸ„αž™αž—αžΆαž–αž‘αž“αŸ‹αž—αŸ’αž›αž“αŸ‹αŸ”

αž’αŸ’αž“αž€αžšαžαŸ‹αžαž»

αž™αž›αŸ‹αž–αŸ’αžšαž˜ αžαžΎβ€‹αž™αžΎαž„β€‹αžŠαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™β€‹αž”αž‰αŸ’αž αžΆβ€‹αž‡αžΆαž”αŸ‹αž‚αžΆαŸ†αž„ αž€αžΆαžšαž’αžαŸ‹αžƒαŸ’αž›αžΆαž“ αž“αž·αž„β€‹αž€αžΆαžšαžŸαŸ’αž›αžΆαž”αŸ‹β€‹αž“αŸαŸ‡β€‹αžŠαŸ„αž™β€‹αžšαž”αŸ€αž”αžŽαžΆ? αž™αžΎαž„β€‹αž“αžΉαž„β€‹αž’αž“αž»αž‰αŸ’αž‰αžΆαžβ€‹αž±αŸ’αž™β€‹αž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌβ€‹αžαŸ‚β€‹αž˜αŸ’αž“αžΆαž€αŸ‹β€‹αž‚αžαŸ‹β€‹αž‘αŸ…β€‹αž€αžΆαž“αŸ‹β€‹αžŸαž˜ αž αžΎαž™β€‹αž™αžΎαž„β€‹αž“αžΉαž„β€‹αž”αž“αŸ’αžαŸ‚αž˜β€‹αž€αžΆαžšβ€‹αž˜αž·αž“β€‹αžšαžΆαž”αŸ‹β€‹αž”αž‰αŸ’αž…αžΌαž›β€‹αž‚αŸ’αž“αžΆβ€‹αž‘αŸ…β€‹αžœαž·αž‰β€‹αž‘αŸ…β€‹αž˜αž€β€‹αž“αŸƒβ€‹αžαŸ’αžŸαŸ‚αžŸαŸ’αžšαž‘αžΆαž™β€‹αžŸαž˜αŸ’αžšαžΆαž”αŸ‹β€‹αž€αž“αŸ’αž›αŸ‚αž„β€‹αž“αŸαŸ‡αŸ” αžαžΎαžαŸ’αžšαžΌαžœαž’αŸ’αžœαžΎαžŠαžΌαž…αž˜αŸ’αžαŸαž…? αž§αž”αž˜αžΆαžαžΆ αž“αŸ…αž€αŸ’αž”αŸ‚αžšαž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌ αž˜αžΆαž“αž’αŸ’αž“αž€αžšαžαŸ‹αžαž»αž˜αŸ’αž“αžΆαž€αŸ‹ αžŠαŸ‚αž›αž’αž“αž»αž‰αŸ’αž‰αžΆαžαž·αž±αŸ’αž™αž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌαž˜αŸ’αž“αžΆαž€αŸ‹αž™αž€αžŸαž˜αŸ” αžαžΎαž™αžΎαž„αž‚αž½αžšαž”αž„αŸ’αž€αžΎαžαž’αŸ’αž“αž€αžšαžαŸ‹αžαž»αž“αŸαŸ‡αžŠαŸ„αž™αžšαž”αŸ€αž”αžŽαžΆ αž αžΎαž™αžαžΎαž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌαž“αžΉαž„αžŸαž½αžšαž‚αžΆαžαŸ‹αžŠαŸ„αž™αžšαž”αŸ€αž”αžŽαžΆ αž‚αžΊαž‡αžΆαžŸαŸ†αžŽαž½αžšαž‚αž½αžšαž±αŸ’αž™αž…αžΆαž”αŸ‹αž’αžΆαžšαž˜αŸ’αž˜αžŽαŸαŸ”

αž˜αž’αŸ’αž™αŸ„αž”αžΆαž™αžŠαŸαžŸαžΆαž˜αž‰αŸ’αž‰αž”αŸ†αž•αž»αžαž‚αžΊαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌαž‚αŸ’αžšαžΆαž“αŸ‹αžαŸ‚αžŸαž½αžšαž’αŸ’αž“αž€αžšαžαŸ‹αžαž»αž±αŸ’αž™αž‡αžΆαž”αŸ‹αž‡αžΆαž“αž·αž…αŸ’αž…αŸ” αž‘αžΆαŸ†αž„αž“αŸ„αŸ‡αŸ” αž₯αž‘αžΌαžœαž“αŸαŸ‡αž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌαž“αžΉαž„αž˜αž·αž“αžšαž„αŸ‹αž…αžΆαŸ†αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžŸαž˜αž“αŸ…αž€αŸ’αž”αŸ‚αžšαž“αŸ„αŸ‡αž‘αŸαžαŸ‚αžšαž„αŸ‹αž…αžΆαŸ†αž¬αžŸαž½αžšαž’αŸ’αž“αž€αžšαžαŸ‹αžαž»αŸ” αžŠαŸ†αž”αžΌαž„αž‘αžΎαž™ αž™αžΎαž„αž”αŸ’αžšαžΎαžαŸ‚ User Space αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžœαžΆ αž αžΎαž™αž“αŸ…αž€αŸ’αž“αž»αž„αž“αŸ„αŸ‡ αž™αžΎαž„αž˜αž·αž“αž”αŸ’αžšαžΎαž€αžΆαžšαžšαŸ†αžαžΆαž“αžŠαžΎαž˜αŸ’αž”αžΈαž αŸ…αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžŽαžΆαž˜αž½αž™αž–αžΈαžαžΊαžŽαŸ‚αž›αž‘αŸ (αž”αž“αŸ’αžαŸ‚αž˜αž›αžΎαž–αž½αž€αžœαžΆαžαžΆαž„αž€αŸ’αžšαŸ„αž˜)αŸ”

αžŠαŸ†αžŽαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αž‘αŸ†αž αŸ†αž’αŸ’αž“αž€αž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹

αž“αŸ…αž‘αžΈαž“αŸαŸ‡αž™αžΎαž„αž“αžΉαž„αž’αŸ’αžœαžΎαžŠαžΌαž…αž‚αŸ’αž“αžΆαžŠαŸ‚αž›αž™αžΎαž„αž”αžΆαž“αž’αŸ’αžœαžΎαž–αžΈαž˜αž»αž“αž‡αžΆαž˜αž½αž™αž“αžΉαž„αžŸαž˜αž˜αž½αž™ αž“αž·αž„αž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌαž–αžΈαžšαž“αžΆαž€αŸ‹ αž™αžΎαž„αž“αžΉαž„αž”αž„αŸ’αžœαž·αž›αžšαž„αŸ’αžœαž·αž›αž‡αž»αŸ†αž˜αž½αž™ αž αžΎαž™αžšαž„αŸ‹αž…αžΆαŸ†αŸ” αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž₯αž‘αžΌαžœαž“αŸαŸ‡ αžœαžΆαž“αžΉαž„αž€αŸ’αž›αžΆαž™αž‡αžΆαž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌαž‘αžΆαŸ†αž„αž’αžŸαŸ‹ αž αžΎαž™αžŠαžΌαž…αžŠαŸ‚αž›αžœαžΆαž’αŸ’αž›αžΆαž”αŸ‹αž˜αžΆαž“ αž˜αžΆαž“αžαŸ‚αžŸαž˜αž˜αž½αž™αž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡ αž–αŸ„αž›αž‚αžΊαž§αŸ” αž™αžΎαž„β€‹αž’αžΆαž…β€‹αž“αž·αž™αžΆαž™β€‹αž”αžΆαž“β€‹αžαžΆβ€‹αž˜αžΆαž“β€‹αžαŸ‚β€‹αž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌβ€‹αž˜αŸ’αž“αžΆαž€αŸ‹β€‹αž‚αžαŸ‹β€‹αžŠαŸ‚αž›β€‹αž”αžΆαž“β€‹αž™αž€β€‹Β«β€‹αž€αŸ†αž”αŸ„αžšβ€‹αž˜αžΆαžŸβ€‹Β»β€‹αž–αžΈβ€‹αž’αŸ’αž“αž€β€‹αžšαžαŸ‹β€‹αžαž»β€‹αž“αžΉαž„β€‹αžŸαŸŠαžΈαŸ” αžŠαžΎαž˜αŸ’αž”αžΈαž’αŸ’αžœαžΎαžŠαžΌαž…αž“αŸαŸ‡αž™αžΎαž„αž”αŸ’αžšαžΎ 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 (αžŠαŸ‚αž›αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ’αžšαžΎαž“αŸ…αž‘αžΈαž“αŸ„αŸ‡) αŸ” αž₯αž‘αžΌαžœαž“αŸαŸ‡αž‚αžΆαžαŸ‹αžŠαžΉαž„αž–αžΈαžšαž”αŸ€αž”αžšαžΆαž”αŸ‹αž’αŸ’αž“αž€αžŠαŸ‚αž›αžšαž„αŸ‹αž…αžΆαŸ† αžŠαžΆαž€αŸ‹αž–αž½αž€αž‚αŸαž±αŸ’αž™αžŠαŸαž€αž”αž“αŸ’αžαž·αž… αž“αž·αž„αž…αŸ’αžšαžΎαž“αž‘αŸ€αžαŸ” αž›αŸ” αž‡αžΆαž‘αžΌαž‘αŸ… αžœαžΆαž’αŸ’αžœαžΎαž’αŸ’αžœαžΈαž‚αŸ’αžšαž”αŸ‹αž™αŸ‰αžΆαž„αžŠαŸ‚αž›αž’αžΆαž…αž’αŸ’αžœαžΎαž‘αŸ…αž”αžΆαž“αžŠαžΎαž˜αŸ’αž”αžΈαž”αž„αŸ’αž€αžΎαž“αž”αŸ’αžšαžŸαž·αž‘αŸ’αž’αž—αžΆαž–αŸ” αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž™αžΎαž„αžαŸ’αžšαžΌαžœαžαŸ‚αž…αž„αž…αžΆαŸ†αžαžΆ αž“αŸαŸ‡αž“αŸ…αžαŸ‚αž‡αžΆαžšαž„αŸ’αžœαž·αž›αž‡αž»αŸ†αžŸαž€αž˜αŸ’αž˜αžŠαžŠαŸ‚αž›αžŠαŸ‚αž›αžŸαŸŠαžΈαž’αž“αž’αžΆαž“αžŠαŸ†αžŽαžΎαžšαž€αžΆαžš αž“αž·αž„αž€αžΆαž“αŸ‹αžαŸ’αžŸαŸ‚ αžŠαŸ‚αž›αž’αžΆαž…αž“αžΆαŸ†αž‘αŸ…αžšαž€αž—αžΆαž–αž’αžαŸ‹αžƒαŸ’αž›αžΆαž“ αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌαž˜αŸ’αž“αžΆαž€αŸ‹αž€αŸ’αž›αžΆαž™αž‡αžΆαž’αžΆαž‘αž·αž—αžΆαž–αž‡αžΆαž„αž’αŸ’αž“αž€αž•αŸ’αžŸαŸαž„αž‘αŸ€αž αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž˜αž·αž“αž˜αžΆαž“αžŸαž˜αž˜αžΆαžŸαž‘αŸ (αž”αž‰αŸ’αž αžΆαž’αžΆαž‘αž·αž—αžΆαž–αž”αž‰αŸ’αž…αŸ’αžšαžΆαžŸ ) αžŠαžΌαž…αŸ’αž“αŸαŸ‡αž αžΎαž™ αž™αžΎαž„αž”αŸ’αžšαžΎαžœαžΆαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžαŸ‚αž€αžΆαžšαž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαžŠαŸαžαŸ’αž›αžΈαž”αŸ†αž•αž»αžαž“αŸ…αž€αŸ’αž“αž»αž„αž’αž„αŸ’αž‚αž…αž„αž…αžΆαŸ†αžŠαŸ‚αž›αž”αžΆαž“αž…αŸ‚αž€αžšαŸ†αž›αŸ‚αž€αž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡ αžŠαŸ„αž™αž‚αŸ’αž˜αžΆαž“αž€αžΆαžšαž αŸ…αž‘αžΌαžšαžŸαž–αŸ’αž‘αž—αžΆαž‚αžΈαž‘αžΈαž”αžΈ αž€αžΆαžšαž…αžΆαž€αŸ‹αžŸαŸ„αžšαž‡αžΆαž”αŸ‹αž‚αŸ’αž“αžΆ αž¬αž€αžΆαžšαž—αŸ’αž‰αžΆαž€αŸ‹αž•αŸ’αž’αžΎαž›αž•αŸ’αžŸαŸαž„αž‘αŸ€αžαŸ”

Well-Fed Philosophers ឬ Competitive .NET Programming

αž‚αžΌαžšαžŸαž˜αŸ’αžšαžΆαž”αŸ‹ SpinLock. αžŸαŸ’αž‘αŸ’αžšαžΈαž˜αž€αŸ†αž–αž»αž„ "αž”αŸ’αžšαž™αž»αž‘αŸ’αž’" αž‡αžΆαž“αž·αž…αŸ’αž…αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžŸαž˜αž˜αžΆαžŸαŸ” αž€αžΆαžšαž”αžšαžΆαž‡αŸαž™αž€αžΎαžαž‘αžΎαž„ - αžαŸ†αž”αž“αŸ‹αžŠαŸ‚αž›αž”αžΆαž“αž”αž“αŸ’αž›αž·αž…αž“αŸ…αž€αŸ’αž“αž»αž„αžšαžΌαž”αž—αžΆαž–αŸ” αžŸαŸ’αž“αžΌαž›αž˜αž·αž“αžαŸ’αžšαžΌαžœαž”αžΆαž“αž‚αŸαž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αž–αŸαž‰αž›αŸαž‰αž‘αŸ: αž˜αžΆαž“αžαŸ‚αž”αŸ’αžšαž αŸ‚αž› 2/3 αžŠαŸ„αž™αžαŸ’αžŸαŸ‚αžŸαŸ’αžšαž‘αžΆαž™αž‘αžΆαŸ†αž„αž”αž½αž“αž“αŸαŸ‡αŸ”

αžŠαŸ†αžŽαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αž˜αž½αž™αž‘αŸ€αžαž“αŸ…αž‘αžΈαž“αŸαŸ‡αž‚αžΊαž‚αŸ’αžšαžΆαž“αŸ‹αžαŸ‚αž”αŸ’αžšαžΎ Interlocked.CompareExchange αž‡αžΆαž˜αž½αž™αž“αžΉαž„αž€αžΆαžšαžšαž„αŸ‹αž…αžΆαŸ†αžŸαž€αž˜αŸ’αž˜αžŠαžΌαž…αž‚αŸ’αž“αžΆαžŠαžΌαž…αžŠαŸ‚αž›αž”αžΆαž“αž”αž„αŸ’αž αžΆαž‰αž“αŸ…αž€αŸ’αž“αž»αž„αž€αžΌαžŠαžαžΆαž„αž›αžΎ (αž“αŸ…αž€αŸ’αž“αž»αž„αž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌαžŠαŸ‚αž›αžŸαŸ’αžšαŸαž€αžƒαŸ’αž›αžΆαž“) αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž“αŸαŸ‡ αžŠαžΌαž…αžŠαŸ‚αž›αž”αžΆαž“αž“αž·αž™αžΆαž™αžšαž½αž…αž˜αž€αž αžΎαž™ αž‘αŸ’αžšαžΉαžŸαŸ’αžαžΈαž’αžΆαž…αž“αžΆαŸ†αž‘αŸ…αžŠαž›αŸ‹αž€αžΆαžšαž‘αž”αŸ‹αžŸαŸ’αž€αžΆαžαŸ‹αŸ”

αž“αŸ…αž›αžΎ Interlocked αžœαžΆαž‚αžΊαž˜αžΆαž“αžαŸ†αž›αŸƒαž“αž·αž™αžΆαž™αžαžΆαž˜αžΆαž“αž˜αž·αž“αžαŸ’αžšαžΉαž˜αžαŸ‚ CompareExchangeαž”αŸ‰αž»αž“αŸ’αžαŸ‚αž€αŸαž˜αžΆαž“αžœαž·αž’αžΈαžŸαžΆαžŸαŸ’αžšαŸ’αžαž•αŸ’αžŸαŸαž„αž‘αŸ€αžαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž’αžΆαž“ αž“αž·αž„αž€αžΆαžšαžŸαžšαžŸαŸαžšαž’αžΆαžαžΌαž˜αž•αž„αžŠαŸ‚αžšαŸ” αž αžΎαž™αžαžΆαž˜αžšαž™αŸˆαž€αžΆαžšαž’αŸ’αžœαžΎαž€αžΆαžšαž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαž˜αŸ’αžαž„αž‘αŸ€αž αž”αŸ’αžšαžŸαž·αž“αž”αžΎαžαŸ’αžŸαŸ‚αžŸαŸ’αžšαž‘αžΆαž™αž•αŸ’αžŸαŸαž„αž‘αŸ€αžαž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„αž€αžΆαžšαž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαžšαž”αžŸαŸ‹αžœαžΆ (αž’αžΆαž“ 1 αž’αžΆαž“ 2 សរសេរ 2 សរសេរ 1 αž‚αžΊαž’αžΆαž€αŸ’αžšαž€αŸ‹) αžœαžΆαž’αžΆαž…αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αŸ’αžšαžΎαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαžŸαŸ’αž˜αž»αž‚αŸ’αžšαžŸαŸ’αž˜αžΆαž‰αž‘αŸ…αž“αžΉαž„αžαž˜αŸ’αž›αŸƒαž˜αž½αž™ (αž›αŸ†αž“αžΆαŸ†αž’αž“αŸ’αžαžšαž€αž˜αŸ’αž˜αžŽαžΆαž˜αž½αž™) αŸ”

αžŠαŸ†αžŽαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αžšαž”αŸ€αž”αžαžΊαžŽαŸ‚αž›

αžŠαžΎαž˜αŸ’αž”αžΈαž‡αŸ€αžŸαžœαžΆαž„αž€αžΆαžšαžαŸ’αž‡αŸ‡αžαŸ’αž‡αžΆαž™αž’αž“αž’αžΆαž“αž“αŸ…αž€αŸ’αž“αž»αž„αžšαž„αŸ’αžœαž·αž›αž‡αž»αŸ†αž˜αž½αž™ αžŸαžΌαž˜αž˜αžΎαž›αž–αžΈαžšαž”αŸ€αž”αžŠαžΎαž˜αŸ’αž”αžΈαžšαžΆαžšαžΆαŸ†αž„αžαŸ’αžŸαŸ‚αžŸαŸ’αžšαž‘αžΆαž™αŸ” αž˜αŸ‰αŸ’αž™αžΆαž„αž‘αŸ€αž αž€αžΆαžšαž”αž“αŸ’αžαž§αž‘αžΆαž αžšαžŽαŸαžšαž”αžŸαŸ‹αž™αžΎαž„ αžŸαžΌαž˜αž˜αžΎαž›αž–αžΈαžšαž”αŸ€αž”αžŠαŸ‚αž›αž’αŸ’αž“αž€αžšαžαŸ‹αžαž»αžŠαžΆαž€αŸ‹αž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌαž±αŸ’αž™αžŠαŸαž€ αž αžΎαž™αžŠαžΆαžŸαŸ‹αž‚αžΆαžαŸ‹αž±αŸ’αž™αž—αŸ’αž‰αžΆαž€αŸ‹αžαŸ‚αž–αŸαž›αž…αžΆαŸ†αž”αžΆαž…αŸ‹αž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡αŸ” αž‡αžΆαžŠαŸ†αž”αžΌαž„ αžŸαžΌαž˜αž€αŸ’αžšαž‘αŸαž€αž˜αžΎαž›αžšαž”αŸ€αž”αž’αŸ’αžœαžΎαžœαžΆαžαžΆαž˜αžšαž™αŸˆαžšαž”αŸ€αž”αžαžΊαžŽαŸ‚αž›αž“αŸƒαž”αŸ’αžšαž–αŸαž“αŸ’αž’αž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž€αžΆαžšαŸ” αžšαž…αž“αžΆαžŸαž˜αŸ’αž–αŸαž“αŸ’αž’αž‘αžΆαŸ†αž„αž’αžŸαŸ‹αž“αŸ…αž‘αžΈαž“αŸ„αŸ‡αž…αŸ’αžšαžΎαž“αžαŸ‚αž”αž‰αŸ’αž…αž”αŸ‹αž™αžΊαžαž‡αžΆαž„αž€αž“αŸ’αž›αŸ‚αž„αž”αŸ’αžšαžΎαž”αŸ’αžšαžΆαžŸαŸ‹αŸ” αž™αžΊαžαž…αŸ’αžšαžΎαž“αžŠαž„ αž‡αžΆαž§αž‘αžΆαž αžšαžŽαŸ AutoResetEvent αž”αŸ’αžšαž αŸ‚αž›αž‡αžΆ 53 αžŠαž„αž™αžΊαžαž‡αžΆαž„ SpinLock [αžšαž·αž…αž‘αŸαžš] αŸ” αž”αŸ‰αž»αž“αŸ’αžαŸ‚αžŠαŸ„αž™αž˜αžΆαž“αž‡αŸ†αž“αž½αž™αžšαž”αžŸαŸ‹αž–αž½αž€αž‚αŸ αž’αŸ’αž“αž€αž’αžΆαž…αž’αŸ’αžœαžΎαžŸαž˜αž€αžΆαž›αž€αž˜αŸ’αž˜αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαž“αŸ…αž‘αžΌαž‘αžΆαŸ†αž„αž”αŸ’αžšαž–αŸαž“αŸ’αž’αž‘αžΆαŸ†αž„αž˜αžΌαž› αž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„αž¬αž’αžαŸ‹αŸ”

αž€αžΆαžšαžšαž…αž“αžΆαž‡αžΆαž˜αžΌαž›αžŠαŸ’αž‹αžΆαž“αž“αŸ…αž‘αžΈαž“αŸαŸ‡αž‚αžΊαž‡αžΆ semaphore αžŠαŸ‚αž›αžŸαŸ’αž“αžΎαž‘αžΎαž„αžŠαŸ„αž™ Dijkstra αž‡αžΆαž„αž€αž“αŸ’αž›αŸ‡αžŸαžαžœαžαŸ’αžŸαž˜αž»αž“αŸ” Semaphore αž‚αžΊαž“αž·αž™αžΆαž™αžŠαŸ„αž™αžŸαžΆαž˜αž‰αŸ’αž‰αžαžΆ αž…αŸ†αž“αž½αž“αž‚αžαŸ‹αžœαž·αž‡αŸ’αž‡αž˜αžΆαž“αžŠαŸ‚αž›αž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„αžŠαŸ„αž™αž”αŸ’αžšαž–αŸαž“αŸ’αž’ αž“αž·αž„αž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž€αžΆαžšαž–αžΈαžšαž“αŸ…αž›αžΎαžœαžΆ - αž”αž„αŸ’αž€αžΎαž“ αž“αž·αž„αž”αž“αŸ’αžαž™αŸ” αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž˜αž·αž“αž’αžΆαž…αž€αžΆαžαŸ‹αž”αž“αŸ’αžαž™αžŸαžΌαž“αŸ’αž™αž”αžΆαž“αž‘αŸαž“αŸ„αŸ‡ αžαŸ’αžŸαŸ‚αž‘αžΌαžšαžŸαŸαž–αŸ’αž‘αžαŸ’αžšαžΌαžœαž”αžΆαž“αžšαžΆαžšαžΆαŸ†αž„αŸ” αž“αŸ…αž–αŸαž›αžŠαŸ‚αž›αž…αŸ†αž“αž½αž“αžαŸ’αžšαžΌαžœαž”αžΆαž“αž€αžΎαž“αž‘αžΎαž„αžŠαŸ„αž™αžαŸ’αžŸαŸ‚αžŸαŸ’αžšαž‘αžΆαž™/αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžŸαž€αž˜αŸ’αž˜αž˜αž½αž™αž…αŸ†αž“αž½αž“αž•αŸ’αžŸαŸαž„αž‘αŸ€αž αž“αŸ„αŸ‡αžαŸ’αžŸαŸ‚αžŸαŸ’αžšαž‘αžΆαž™αžαŸ’αžšαžΌαžœαž”αžΆαž“αž†αŸ’αž›αž„αž€αžΆαžαŸ‹ αž αžΎαž™ semaphore αžαŸ’αžšαžΌαžœαž”αžΆαž“αž€αžΆαžαŸ‹αž”αž“αŸ’αžαž™αž˜αŸ’αžαž„αž‘αŸ€αžαžŠαŸ„αž™αž…αŸ†αž“αž½αž“αžŠαŸ‚αž›αž”αžΆαž“αž†αŸ’αž›αž„αž€αžΆαžαŸ‹αŸ” αž’αŸ’αž“αž€β€‹αž’αžΆαž…β€‹αžŸαŸ’αžšαž˜αŸƒβ€‹αž˜αžΎαž›β€‹αžšαžαž—αŸ’αž›αžΎαž„β€‹αž“αŸ…β€‹αž€αŸ’αž“αž»αž„β€‹αž€αžΆαžšβ€‹αž€αž€αžŸαŸ’αž‘αŸ‡β€‹αž‡αžΆαž˜αž½αž™β€‹αž“αžΉαž„β€‹αžŸαž‰αŸ’αž‰αžΆβ€‹αžŸαž˜αŸ’αž‚αžΆαž›αŸ‹αŸ” .NET αž•αŸ’αžαž›αŸ‹αž“αžΌαžœαžŸαŸ†αžŽαž„αŸ‹αž‡αžΆαž…αŸ’αžšαžΎαž“αžŠαŸ‚αž›αž˜αžΆαž“αž˜αž»αžαž„αžΆαžšαžŸαŸ’αžšαžŠαŸ€αž„αž‚αŸ’αž“αžΆαŸ– AutoResetEvent, ManualResetEvent, Mutex αž“αž·αž„αžαŸ’αž›αž½αž“αžαŸ’αž‰αž»αŸ†αž•αŸ’αž‘αžΆαž›αŸ‹ Semaphore. αž™αžΎαž„αž“αžΉαž„αž”αŸ’αžšαžΎ AutoResetEventαž“αŸαŸ‡β€‹αž‚αžΊβ€‹αž‡αžΆβ€‹αž€αžΆαžšβ€‹αžŸαžΆαž˜αž‰αŸ’αž‰β€‹αž”αŸ†αž•αž»αžβ€‹αž“αŸƒβ€‹αž€αžΆαžšβ€‹αžŸαžΆαž„β€‹αžŸαž„αŸ‹β€‹αž‘αžΆαŸ†αž„β€‹αž“αŸαŸ‡αŸ– αž˜αžΆαž“β€‹αžαŸ‚β€‹αžαž˜αŸ’αž›αŸƒβ€‹αž–αžΈαžš ០ αž“αž·αž„ ៑ (αž˜αž·αž“β€‹αž–αž·αž αž–αž·αž)αŸ” αžœαž·αž’αžΈαžŸαžΆαžŸαŸ’αžšαŸ’αžαžšαž”αžŸαŸ‹αž“αžΆαž„ WaitOne() αžšαžΆαžšαžΆαŸ†αž„β€‹αžαŸ’αžŸαŸ‚β€‹αž€αžΆαžšβ€‹αž αŸ…β€‹αž‘αžΌαžšαžŸαž–αŸ’αž‘ αž”αŸ’αžšαžŸαž·αž“αž”αžΎβ€‹αžαž˜αŸ’αž›αŸƒβ€‹αž‚αžΊ 0 αž αžΎαž™β€‹αž”αŸ’αžšαžŸαž·αž“αž”αžΎ 1 αž“αŸ„αŸ‡β€‹αž‘αž˜αŸ’αž›αžΆαž€αŸ‹β€‹αžœαžΆβ€‹αž‘αŸ… 0 αž αžΎαž™β€‹αžšαŸ†αž›αž„β€‹αžœαžΆαŸ” αžœαž·αž’αžΈαžŸαžΆαžŸαŸ’αžšαŸ’αžαž˜αž½αž™αŸ” Set() αž€αžΎαž“αž‘αžΎαž„αžŠαž›αŸ‹ 1 αž“αž·αž„αž’αž“αž»αž‰αŸ’αž‰αžΆαžαž±αŸ’αž™αž˜αž“αž»αžŸαŸ’αžŸαž˜αŸ’αž“αžΆαž€αŸ‹αž†αŸ’αž›αž„αž€αžΆαžαŸ‹ αžŠαŸ‚αž›αž˜αŸ’αžαž„αž‘αŸ€αžαž”αž“αŸ’αžαž™αž˜αž€αžαŸ’αžšαžΉαž˜ 0αŸ” αž’αŸ’αžœαžΎαžŸαž€αž˜αŸ’αž˜αž—αžΆαž–αžŠαžΌαž…αž‡αžΆ turnstile αž“αŸ…αž€αŸ’αž“αž»αž„αžšαžαž—αŸ’αž›αžΎαž„αž€αŸ’αžšαŸ„αž˜αžŠαžΈαŸ”

αž…αžΌαžšαž’αŸ’αžœαžΎαž±αŸ’αž™αžŸαŸ’αž˜αž»αž‚αžŸαŸ’αž˜αžΆαž‰αžŠαž›αŸ‹αžŠαŸ†αžŽαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™ αž αžΎαž™αž”αŸ’αžšαžΎαž€αžΆαžšαž‘αž”αŸ‹αžŸαŸ’αž€αžΆαžαŸ‹αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌαž˜αŸ’αž“αžΆαž€αŸ‹αŸ— αž αžΎαž™αž˜αž·αž“αž˜αŸ‚αž“αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž‘αžΆαŸ†αž„αž’αžŸαŸ‹αž‚αŸ’αž“αžΆαž€αŸ’αž“αž»αž„αž–αŸαž›αžαŸ‚αž˜αž½αž™αž“αŸ„αŸ‡αž‘αŸαŸ” αž‘αžΆαŸ†αž„αž“αŸ„αŸ‡αŸ” αž₯αž‘αžΌαžœβ€‹αž“αŸαŸ‡ αž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌβ€‹αž‡αžΆαž…αŸ’αžšαžΎαž“β€‹αž’αžΆαž…β€‹αž‰αŸ‰αžΆαŸ†β€‹αž€αŸ’αž“αž»αž„αž–αŸαž›αžαŸ‚αž˜αž½αž™ αž αžΎαž™β€‹αž˜αž·αž“αž˜αŸ‚αž“β€‹αžαŸ‚αž˜αž½αž™β€‹αž˜αž»αžβ€‹αž‘αŸαŸ” αž”αŸ‰αž»αž“αŸ’αžαŸ‚ αž™αžΎαž„β€‹αž”αž·αž‘β€‹αž€αžΆαžšβ€‹αž…αžΌαž›β€‹αž‘αŸ…β€‹αžαž»β€‹αž˜αŸ’αžŠαž„β€‹αž‘αŸ€αž αžŠαžΎαž˜αŸ’αž”αžΈβ€‹αž™αž€β€‹αžŸαž˜β€‹αž”αžΆαž“β€‹αžαŸ’αžšαžΉαž˜β€‹αžαŸ’αžšαžΌαžœ αž‡αŸ€αžŸαžœαžΆαž„β€‹αž›αž€αŸ’αžαžαžŽαŸ’αžŒβ€‹αž€αžΆαžšβ€‹αž”αŸ’αžšαžŽαžΆαŸ†αž„αŸ”

// Для блокирования ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ философа.
// Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ΡΡ: 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 αž“αŸαŸ‡αž‚αžΊαž‡αžΆ semaphore αžŠαžΌαž…αž‚αŸ’αž“αžΆαž‡αžΆαž˜αž½αž™αž“αžΉαž„αžαž˜αŸ’αž›αŸƒαž’αžαž·αž”αžšαž˜αžΆαž“αŸƒ 1 (mutex) αž”αŸ‰αž»αž“αŸ’αžαŸ‚αž‡αžΆαž˜αž½αž™αž“αžΉαž„αž€αžΆαžšαž‚αžΆαŸ†αž‘αŸ’αžšαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαžšαž„αŸ‹αž…αžΆαŸ†αž“αŸ…αž€αŸ’αž“αž»αž„αžšαž„αŸ’αžœαž·αž›αž‡αž»αŸ† αž€αžΆαžšαž”αž„αŸ’αž€αžΎαžαž‘αžΎαž„αžœαž·αž‰ αž›αž€αŸ’αžαžαžŽαŸ’αžŒαž’αžαŸαžšαž›αŸ†αž“αžΆαŸ† (αž…αŸ’αžšαžΎαž“αž‘αŸ€αžαž“αŸ…αž›αžΎαž“αŸ„αŸ‡αžαžΆαž„αž€αŸ’αžšαŸ„αž˜) αŸ”αž›αŸ” αžŸαžΌαž˜αž€αŸ’αžšαž‘αŸαž€αž˜αžΎαž›αžŠαŸ†αžŽαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αž‡αžΆαž˜αž½αž™αžœαžΆαŸ”

// БпрячСм ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ для ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€Π° ΠΎΡ‚ всСх, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±Π΅Π· Π΄Π΅Π΄Π»ΠΎΠΊΠΎΠ².
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 αžŠαŸ„αž™αž•αŸ’αž‘αžΆαž›αŸ‹ [Richter] [Eric Lippert] αŸ” αž˜αž½αž™αž€αŸ’αž“αž»αž„αž…αŸ†αžŽαŸ„αž˜αž–αž½αž€αž‚αŸαž‚αžΊαž“αŸ„αŸ‡αŸ” lock αžαŸ‚αž„αžαŸ‚αž…αŸαž‰αž˜αž€ Monitorαž‘αŸ„αŸ‡αž”αžΈαž‡αžΆαž˜αžΆαž“αž€αžšαžŽαžΈαž›αžΎαž€αž›αŸ‚αž„αž˜αž½αž™ αž αžΎαž™αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž˜αž€ αžαŸ’αžŸαŸ‚αž•αŸ’αžŸαŸαž„αž‘αŸ€αžαž’αžΆαž…αž•αŸ’αž›αžΆαžŸαŸ‹αž”αŸ’αžαžΌαžšαžŸαŸ’αžαžΆαž“αž—αžΆαž–αž“αŸƒαž’αž„αŸ’αž‚αž…αž„αž…αžΆαŸ†αžŠαŸ‚αž›αž”αžΆαž“αž…αŸ‚αž€αžšαŸ†αž›αŸ‚αž€αŸ” αž€αŸ’αž“αž»αž„αž€αžšαžŽαžΈαž”αŸ‚αž”αž“αŸαŸ‡ αžœαžΆαž‡αžΆαž€αžΆαžšαž”αŸ’αžšαžŸαžΎαžšαž€αŸ’αž“αž»αž„αž€αžΆαžšαž…αžΌαž›αž‘αŸ…αž€αŸ’αž“αž»αž„αž—αžΆαž–αž‡αžΆαž”αŸ‹αž‚αžΆαŸ†αž„ αž¬αž”αž‰αŸ’αž…αž”αŸ‹αž€αž˜αŸ’αž˜αžœαž·αž’αžΈαžŠαŸ„αž™αžŸαž»αžœαžαŸ’αžαž·αž—αžΆαž–αŸ” αž€αžΆαžšαž—αŸ’αž‰αžΆαž€αŸ‹αž•αŸ’αž’αžΎαž›αž˜αž½αž™αž‘αŸ€αžαž‚αžΊαžαžΆαž˜αŸ‰αžΌαž“αžΈαž‘αŸαžšαž”αŸ’αžšαžΎαž”αŸ’αž›αž»αž€αž“αžΆαž‘αž·αž€αžΆ (SyncBlock) αžŠαŸ‚αž›αž˜αžΆαž“αž“αŸ…αž€αŸ’αž“αž»αž„αžœαžαŸ’αžαž»αž‘αžΆαŸ†αž„αž’αžŸαŸ‹αŸ” αžŠαžΌαž…αŸ’αž“αŸαŸ‡ αž”αŸ’αžšαžŸαž·αž“αž”αžΎαžœαžαŸ’αžαž»αž˜αž·αž“αžŸαž˜αžšαž˜αŸ’αž™αž˜αž½αž™αžαŸ’αžšαžΌαžœαž”αžΆαž“αž‡αŸ’αžšαžΎαžŸαžšαžΎαžŸ αž’αŸ’αž“αž€αž’αžΆαž…αž‘αž‘αž½αž›αž”αžΆαž“αž€αžΆαžšαž‡αžΆαž”αŸ‹αž‚αžΆαŸ†αž„αž”αžΆαž“αž™αŸ‰αžΆαž„αž„αžΆαž™αžŸαŸ’αžšαž½αž› (αž§αž‘αžΆαž αžšαžŽαŸ αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž’αŸ’αž“αž€αž…αžΆαž€αŸ‹αžŸαŸ„αž“αŸ…αž›αžΎαžαŸ’αžŸαŸ‚αž’αž€αŸ’αžŸαžšαžŠαŸ‚αž›αžŠαŸ†αžŽαžΎαžšαž€αžΆαžš)αŸ” αž™αžΎαž„αžαŸ‚αž„αžαŸ‚αž”αŸ’αžšαžΎαžœαžαŸ’αžαž»αž›αžΆαž€αŸ‹αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αžšαžΏαž„αž“αŸαŸ‡αŸ”

αž›αŸ†αž“αžΆαŸ†αž’αžαŸαžšαž›αž€αŸ’αžαžαžŽαŸ’αžŒαž’αž“αž»αž‰αŸ’αž‰αžΆαžαž±αŸ’αž™αž’αŸ’αž“αž€αž’αž“αž»αžœαžαŸ’αžαž€αžΆαžšαžšαŸ†αž–αžΉαž„αž‘αž»αž€αž“αŸƒαž›αž€αŸ’αžαžαžŽαŸ’αžŒαžŸαŸ’αž˜αž»αž‚αžŸαŸ’αž˜αžΆαž‰αž˜αž½αž™αž…αŸ†αž“αž½αž“αŸ” αž“αŸ…αž€αŸ’αž“αž»αž„ .NET αžœαžΆαž˜αž·αž“αž–αŸαž‰αž›αŸαž‰αž‘αŸ αžαžΆαž˜αž‚αŸ†αž“αž·αžαžšαž”αžŸαŸ‹αžαŸ’αž‰αž»αŸ† αž–αŸ’αžšαŸ„αŸ‡... αžαžΆαž˜αž‘αŸ’αžšαžΉαžŸαŸ’αžαžΈ αž‚αž½αžšαžαŸ‚αž˜αžΆαž“αž‡αž½αžšαž‡αžΆαž…αŸ’αžšαžΎαž“αž“αŸ…αž›αžΎαž’αžαŸαžšαž‡αžΆαž…αŸ’αžšαžΎαž“ (αžŠαžΌαž…αž“αŸ…αž€αŸ’αž“αž»αž„ Posix Threads) αž αžΎαž™αž˜αž·αž“αž˜αŸ‚αž“αž“αŸ…αž›αžΎαžŸαŸ„αžαŸ‚αž˜αž½αž™αž‘αŸαŸ” αž”αž“αŸ’αž‘αžΆαž”αŸ‹αž˜αž€αžœαžΆαž“αžΉαž„αž’αžΆαž…αž’αŸ’αžœαžΎαž‘αŸ…αž”αžΆαž“αžŠαžΎαž˜αŸ’αž”αžΈαž’αŸ’αžœαžΎαž±αŸ’αž™αž–αž½αž€αž‚αŸαžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌαž‘αžΆαŸ†αž„αž’αžŸαŸ‹αŸ” αž”αŸ‰αž»αž“αŸ’αžαŸ‚αžŸαžΌαž˜αŸ’αž”αžΈαžαŸ‚αž“αŸ…αž€αŸ’αž“αž»αž„αž‘αž˜αŸ’αžšαž„αŸ‹αž“αŸαŸ‡αžœαžΆαž’αž“αž»αž‰αŸ’αž‰αžΆαžαž±αŸ’αž™αž’αŸ’αž“αž€αžαŸ’αž›αžΈαž€αžΌαžŠαŸ”

αž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌαž‡αžΆαž…αŸ’αžšαžΎαž“αž¬ 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. αžαžΆαž˜αžšαž™αŸˆαžœαžΆ αž’αŸ’αž“αž€αž’αžΆαž…αžšαž„αŸ‹αž…αžΆαŸ†αžœαž·αž’αžΈαžŸαžΆαžŸαŸ’αžαŸ’αžšαž”αž‰αŸ’αž…αž”αŸ‹ αž”αŸ„αŸ‡αž”αž„αŸ‹αžœαžΆ αž“αž·αž„αž’αŸ’αžœαžΈαŸ—αž•αŸ’αžŸαŸαž„αž‘αŸ€αžαžŠαŸ‚αž›αž’αŸ’αž“αž€αž’αžΆαž…αž’αŸ’αžœαžΎαž”αžΆαž“αž‡αžΆαž˜αž½αž™ TaskαŸ” αž“αŸ…αžαžΆαž„αž€αŸ’αž“αž»αž„αžœαž·αž’αžΈαžŸαžΆαžŸαŸ’αžαŸ’αžš αž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αžšαžŠαŸ’αž‹αž‚αŸ’αžšαž”αŸ‹αž‚αŸ’αžšαž„αž€αžΆαžšαž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αŸ” αž…αŸ†αžŽαž»αž…αžŸαŸ†αžαžΆαž“αŸ‹αž‚αžΊαžαžΆαž”αŸ’αžšαžŸαž·αž“αž”αžΎαž‚αŸ’αž˜αžΆαž“αž€αžΆαžšαž–αž“αŸ’αž™αžΆαžšαž–αŸαž›αž‘αŸαž“αŸ„αŸ‡αž€αžΆαžšαž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž‚αžΊαžŸαž˜αž€αžΆαž›αž€αž˜αŸ’αž˜αž αžΎαž™αž”αŸ’αžšαžŸαž·αž“αž”αžΎαž˜αžΆαž“αž“αŸ„αŸ‡αžαŸ’αžŸαŸ‚αžŸαŸ’αžšαž‘αžΆαž™αžαŸ’αžšαžΌαžœαž”αžΆαž“αž”αž‰αŸ’αž…αŸαž‰αŸ” αžŸαž˜αŸ’αžšαžΆαž”αŸ‹αž€αžΆαžšαž™αž›αŸ‹αžŠαžΉαž„αž€αžΆαž“αŸ‹αžαŸ‚αž”αŸ’αžšαžŸαžΎαžšαž‘αžΎαž„ αžœαžΆαž‡αžΆαž€αžΆαžšαž”αŸ’αžšαžŸαžΎαžšαž‡αžΆαž„αž˜αž»αž“αž€αŸ’αž“αž»αž„αž€αžΆαžšαž˜αžΎαž›αž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αžšαžŠαŸ’αž‹αž“αŸαŸ‡αŸ” αž’αŸ’αž“αž€αž’αžΆαž…αž”αž„αŸ’αž€αžΎαžαžαŸ’αžŸαŸ‚αžŸαž„αŸ’αžœαžΆαž€αŸ‹αž‘αžΆαŸ†αž„αž“αŸαŸ‡ async / await αžœαž·αž’αžΈαžŸαžΆαžŸαŸ’αžšαŸ’αžαŸ”

αžαŸ„αŸ‡αžŸαžΆαž€αž›αŸ’αž”αž„αŸ” αž€αžΆαžšαž„αžΆαžšαžšαž”αžŸαŸ‹αž‘αžŸαŸ’αžŸαž“αžœαž·αž‘αžΌ 100 αž“αžΆαž€αŸ‹αž“αŸ…αž›αžΎαž˜αŸ‰αžΆαžŸαŸŠαžΈαž“αžŠαŸ‚αž›αž˜αžΆαž“αžŸαŸ’αž“αžΌαž›αž‘αžΌαž‡αžΈαžαž›αž…αŸ†αž“αž½αž“ 4 αž˜αžΆαž“αžšαž™αŸˆαž–αŸαž› 8 αžœαž·αž“αžΆαž‘αžΈαŸ” αžŠαŸ†αžŽαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αž–αžΈαž˜αž»αž“αž‡αžΆαž˜αž½αž™ Monitor αž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αžαŸ‚ 4 threads αžŠαŸ†αž”αžΌαž„αž”αŸ‰αž»αžŽαŸ’αžŽαŸ„αŸ‡ αž αžΎαž™αž˜αž·αž“αž”αžΆαž“αž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž’αŸ’αžœαžΈαžŠαŸ‚αž›αž“αŸ…αžŸαž›αŸ‹αž‘αžΆαž›αŸ‹αžαŸ‚αžŸαŸ„αŸ‡αŸ” αžαŸ’αžŸαŸ‚αžŸαŸ’αžšαž›αžΆαž™αž‘αžΆαŸ†αž„ 4 αž“αžΈαž˜αž½αž™αŸ—αžαŸ’αžšαžΌαžœαž”αžΆαž“αž‘αž»αž€αž…αŸ„αž›αž”αŸ’αžšαž αŸ‚αž› 2ms αŸ” αž αžΎαž™αžŠαŸ†αžŽαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™ async/await αž”αžΆαž“αž’αŸ’αžœαžΎαž‘αžΆαŸ†αž„αž’αžŸαŸ‹ 100 αžŠαŸ„αž™αž‡αžΆαž˜αž’αŸ’αž™αž˜ 6.8 αžœαž·αž“αžΆαž‘αžΈαžšαžΆαž›αŸ‹αž€αžΆαžšαžšαž„αŸ‹αž…αžΆαŸ†αŸ” αž‡αžΆαž€αžΆαžšαž–αž·αžαžŽαžΆαžŸαŸ‹ αž“αŸ…αž€αŸ’αž“αž»αž„αž”αŸ’αžšαž–αŸαž“αŸ’αž’αž–αž·αž αž€αžΆαžšαž“αŸ…αž‘αŸ†αž“αŸαžšαžšαž™αŸˆαž–αŸαž› 6 αžœαž·αž“αžΆαž‘αžΈαž‚αžΊαž˜αž·αž“αž’αžΆαž…αž‘αž‘αž½αž›αž™αž€αž”αžΆαž“αž‘αŸ αž αžΎαž™αžœαžΆαž‡αžΆαž€αžΆαžšαž”αŸ’αžšαžŸαžΎαžšαž‡αžΆαž„αž€αž»αŸ†αžŠαŸ†αžŽαžΎαžšαž€αžΆαžšαžŸαŸ†αžŽαžΎαž‡αžΆαž…αŸ’αžšαžΎαž“αžαžΆαž˜αžœαž·αž’αžΈαž“αŸαŸ‡αŸ” αžŠαŸ†αžŽαŸ„αŸ‡αžŸαŸ’αžšαžΆαž™αž‡αžΆαž˜αž½αž™ Monitor αž”αŸ’αžšαŸ‚αžαžΆαž˜αž·αž“αž’αžΆαž…αž’αŸ’αžœαžΎαž˜αžΆαžαŸ’αžšαžŠαŸ’αž‹αžΆαž“αž”αžΆαž“αž‘αžΆαž›αŸ‹αžαŸ‚αžŸαŸ„αŸ‡αŸ”

αžŸαŸαž…αž€αŸ’αžαžΈαžŸαž“αŸ’αž“αž·αžŠαŸ’αž‹αžΆαž“

αžŠαžΌαž…αžŠαŸ‚αž›αž’αŸ’αž“αž€αž’αžΆαž…αž˜αžΎαž›αžƒαžΎαž‰αž–αžΈαž§αž‘αžΆαž αžšαžŽαŸαžαžΌαž…αŸ—αž‘αžΆαŸ†αž„αž“αŸαŸ‡ .NET αž‚αžΆαŸ†αž‘αŸ’αžšαž€αžΆαžšαž”αž„αŸ’αž€αžΎαžαžŸαž˜αž€αžΆαž›αž€αž˜αŸ’αž˜αž‡αžΆαž…αŸ’αžšαžΎαž“αŸ” αž‘αŸ„αŸ‡αž™αŸ‰αžΆαž„αžŽαžΆαž€αŸαžŠαŸ„αž™ αžœαžΆαž˜αž·αž“αžαŸ‚αž„αžαŸ‚αž…αŸ’αž”αžΆαžŸαŸ‹αž’αŸ†αž–αžΈαžšαž”αŸ€αž”αž”αŸ’αžšαžΎαž–αž½αž€αžœαžΆαž“αŸ„αŸ‡αž‘αŸαŸ” αžαŸ’αž‰αž»αŸ†αžŸαž„αŸ’αžƒαžΉαž˜αžαžΆαž’αžαŸ’αžαž”αž‘αž“αŸαŸ‡αž˜αžΆαž“αž”αŸ’αžšαž™αŸ„αž‡αž“αŸαŸ” αž™αžΎαž„β€‹αž€αŸ†αž–αž»αž„β€‹αž”αž‰αŸ’αž…αž”αŸ‹β€‹αžœαžΆβ€‹αžŸαž˜αŸ’αžšαžΆαž”αŸ‹β€‹αž–αŸαž›β€‹αž“αŸαŸ‡ αž”αŸ‰αž»αž“αŸ’αžαŸ‚β€‹αžœαžΆβ€‹αž“αŸ…β€‹αž˜αžΆαž“β€‹αžœαžαŸ’αžαž»β€‹αž‚αž½αžšβ€‹αž±αŸ’αž™β€‹αž…αžΆαž”αŸ‹β€‹αž’αžΆαžšαž˜αŸ’αž˜αžŽαŸβ€‹αž‡αžΆβ€‹αž…αŸ’αžšαžΎαž“β€‹αžŠαŸ‚αž›β€‹αž“αŸ…β€‹αžŸαŸαžŸαžŸαž›αŸ‹β€‹αž§αž‘αžΆαž αžšαžŽαŸ αž€αžΆαžšβ€‹αž”αŸ’αžšαž˜αžΌαž›β€‹αžŸαž»αžœαžαŸ’αžαž·αž—αžΆαž–β€‹αžαŸ’αžŸαŸ‚β€‹αž”αžŽαŸ’αžŠαžΆαž‰ TPL Dataflow αž€αžΆαžšβ€‹αžŸαžšαžŸαŸαžšβ€‹αž€αž˜αŸ’αž˜αžœαž·αž’αžΈβ€‹αž”αŸ’αžšαžαž·αž€αž˜αŸ’αž˜ αž‚αŸ†αžšαžΌβ€‹αž”αŸ’αžšαžαž·αž”αžαŸ’αžαž·αž€αžΆαžšβ€‹αž€αž˜αŸ’αž˜αžœαž·αž’αžΈβ€‹αž‡αžΆαžŠαžΎαž˜αŸ”

αž”αŸ’αžšαž—αž–αŸ”

αž”αŸ’αžšαž—αž–: www.habr.com

αž”αž“αŸ’αžαŸ‚αž˜αž˜αžαž·αž™αŸ„αž”αž›αŸ‹