Π”ΠΎΠ±Ρ€ΠΎ Π½Π°Ρ…Ρ€Π°Π½Π΅Ρ‚ΠΈ Ρ„ΠΈΠ»ΠΎΠ·ΠΎΡ„ΠΈ ΠΈΠ»ΠΈ ΠΊΠΎΠ½ΠΊΡƒΡ€Π΅Π½Ρ‚Π½ΠΎ .NET ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°ΡšΠ΅

Π”ΠΎΠ±Ρ€ΠΎ Π½Π°Ρ…Ρ€Π°Π½Π΅Ρ‚ΠΈ Ρ„ΠΈΠ»ΠΎΠ·ΠΎΡ„ΠΈ ΠΈΠ»ΠΈ ΠΊΠΎΠ½ΠΊΡƒΡ€Π΅Π½Ρ‚Π½ΠΎ .NET ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°ΡšΠ΅

АјдС Π΄Π° Π²ΠΈΠ΄ΠΈΠΌΠ΅ ΠΊΠ°ΠΊΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½ΠΈΡ€Π° истоврСмСното ΠΈ ΠΏΠ°Ρ€Π°Π»Π΅Π»Π½ΠΎΡ‚ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°ΡšΠ΅ Π²ΠΎ .Net, ΠΊΠΎΡ€ΠΈΡΡ‚Π΅Ρ˜ΡœΠΈ Π³ΠΎ ΠΊΠ°ΠΊΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΡ‚ со јадСњС Π½Π° Π€ΠΈΠ»ΠΎΠ·ΠΎΡ„ΠΈ. ΠŸΠ»Π°Π½ΠΎΡ‚ Π΅ овој, ΠΎΠ΄ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡ˜Π° Π½Π° нишки/процСси, Π΄ΠΎ ΠΌΠΎΠ΄Π΅Π» Π½Π° Π°ΠΊΡ‚Π΅Ρ€ (Π²ΠΎ слСднитС Π΄Π΅Π»ΠΎΠ²ΠΈ). Π‘Ρ‚Π°Ρ‚ΠΈΡ˜Π°Ρ‚Π° ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΠΈΠ΄Π΅ корисна Π·Π° ΠΏΡ€Π²ΠΎΡ‚ΠΎ запознавањС ΠΈΠ»ΠΈ Π·Π° Π΄Π° Π³ΠΎ освСТитС Π²Π°ΡˆΠ΅Ρ‚ΠΎ знаСњС.

Π—ΠΎΡˆΡ‚ΠΎ Π²ΠΎΠΎΠΏΡˆΡ‚ΠΎ Π΄Π° Π³ΠΎ Π½Π°ΠΏΡ€Π°Π²ΠΈ Ρ‚ΠΎΠ°? ВранзисторитС ја достигнуваат ΡΠ²ΠΎΡ˜Π°Ρ‚Π° ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π½Π° Π³ΠΎΠ»Π΅ΠΌΠΈΠ½Π°, ΠœΡƒΡ€ΠΎΠ²ΠΈΠΎΡ‚ Π·Π°ΠΊΠΎΠ½ сС ΠΏΠΎΡ‚ΠΏΠΈΡ€Π° Π½Π° ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° Π±Ρ€Π·ΠΈΠ½Π°Ρ‚Π° Π½Π° свСтлината ΠΈ Π·Π°Ρ‚ΠΎΠ° сС Π·Π°Π±Π΅Π»Π΅ΠΆΡƒΠ²Π° Π·Π³ΠΎΠ»Π΅ΠΌΡƒΠ²Π°ΡšΠ΅ Π½Π° Π±Ρ€ΠΎΡ˜ΠΎΡ‚, ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π½Π°ΠΏΡ€Π°Π²Π°Ρ‚ повСќС транзистори. Π’ΠΎ исто Π²Ρ€Π΅ΠΌΠ΅, ΠΊΠΎΠ»ΠΈΡ‡ΠΈΠ½Π°Ρ‚Π° Π½Π° ΠΏΠΎΠ΄Π°Ρ‚ΠΎΡ†ΠΈ растС, Π° корисницитС ΠΎΡ‡Π΅ΠΊΡƒΠ²Π°Π°Ρ‚ ΠΈΡ‚Π΅Π½ ΠΎΠ΄Π³ΠΎΠ²ΠΎΡ€ ΠΎΠ΄ систСмитС. Π’ΠΎ Ρ‚Π°ΠΊΠ²Π° ΡΠΈΡ‚ΡƒΠ°Ρ†ΠΈΡ˜Π°, β€žΠ½ΠΎΡ€ΠΌΠ°Π»Π½ΠΎΡ‚ΠΎβ€œ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°ΡšΠ΅, ΠΊΠΎΠ³Π° ΠΈΠΌΠ°ΠΌΠ΅ Π΅Π΄Π½Π° нишка Π·Π° ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°ΡšΠ΅, вСќС Π½Π΅ Π΅ Π΅Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎ. Π’Ρ€Π΅Π±Π° Π½Π΅ΠΊΠ°ΠΊΠΎ Π΄Π° Π³ΠΎ Ρ€Π΅ΡˆΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΡ‚ со истоврСмСно ΠΈΠ»ΠΈ истоврСмСно ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°ΡšΠ΅. ΠŸΠΎΠΊΡ€Π°Ρ˜ Ρ‚ΠΎΠ°, овој ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ постои Π½Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ Π½ΠΈΠ²ΠΎΠ°: Π½Π° Π½ΠΈΠ²ΠΎ Π½Π° нишки, Π½Π° Π½ΠΈΠ²ΠΎ Π½Π° процСси, Π½Π° Π½ΠΈΠ²ΠΎ Π½Π° машини Π²ΠΎ ΠΌΡ€Π΅ΠΆΠ°Ρ‚Π° (дистрибуирани систСми). .NET ΠΈΠΌΠ° висококвалитСтни, врСмСнски тСстирани Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΠΈ Π·Π° Π±Ρ€Π·ΠΎ ΠΈ Сфикасно Ρ€Π΅ΡˆΠ°Π²Π°ΡšΠ΅ Π½Π° Π²Π°ΠΊΠ²ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ.

Π—Π°Π΄Π°Ρ‡Π°

ЕдсгСр Π”ΠΈΡ˜ΠΊΡΡ‚Ρ€Π° ΠΈΠΌ Π³ΠΎ постави овој ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ Π½Π° своитС студСнти ΡƒΡˆΡ‚Π΅ Π²ΠΎ 1965 Π³ΠΎΠ΄ΠΈΠ½Π°. ВоспоставСната Ρ„ΠΎΡ€ΠΌΡƒΠ»Π°Ρ†ΠΈΡ˜Π° Π΅ слСдна. Има ΠΎΠ΄Ρ€Π΅Π΄Π΅Π½ (ΠΎΠ±ΠΈΡ‡Π½ΠΎ ΠΏΠ΅Ρ‚) Π±Ρ€ΠΎΡ˜ Π½Π° Ρ„ΠΈΠ»ΠΎΠ·ΠΎΡ„ΠΈ ΠΈ исто Ρ‚ΠΎΠ»ΠΊΡƒ Π²ΠΈΠ»ΡƒΡˆΠΊΠΈ. Π’ΠΈΠ΅ сСдат Π½Π° Ρ‚Ρ€ΠΊΠ°Π»Π΅Π·Π½Π° маса, со Π²ΠΈΠ»ΡƒΡˆΠΊΠΈ ΠΌΠ΅Ρ“Ρƒ Π½ΠΈΠ². Π€ΠΈΠ»ΠΎΠ·ΠΎΡ„ΠΈΡ‚Π΅ ΠΌΠΎΠΆΠ°Ρ‚ Π΄Π° Ρ˜Π°Π΄Π°Ρ‚ ΠΎΠ΄ своитС Ρ‡ΠΈΠ½ΠΈΠΈ со Π±Π΅ΡΠΊΡ€Π°Ρ˜Π½Π° Ρ…Ρ€Π°Π½Π°, Π΄Π° размислуваат ΠΈΠ»ΠΈ Π΄Π° Ρ‡Π΅ΠΊΠ°Π°Ρ‚. Π—Π° Π΄Π° Ρ˜Π°Π΄Π΅Ρ‚Π΅ Ρ„ΠΈΠ»ΠΎΠ·ΠΎΡ„, Ρ‚Ρ€Π΅Π±Π° Π΄Π° Π·Π΅ΠΌΠ΅Ρ‚Π΅ Π΄Π²Π΅ Π²ΠΈΡ™ΡƒΡˆΠΊΠΈ (послСдната ја Π΄Π΅Π»ΠΈ Π²ΠΈΠ»ΡƒΡˆΠΊΠ°Ρ‚Π° со ΠΏΡ€Π²Π°Ρ‚Π°). ΠŸΠΎΠ΄ΠΈΠ³Π½ΡƒΠ²Π°ΡšΠ΅Ρ‚ΠΎ ΠΈ ΡΠΏΡƒΡˆΡ‚Π°ΡšΠ΅Ρ‚ΠΎ Π½Π° Π²ΠΈΠ»ΡƒΡˆΠΊΠ°Ρ‚Π° сС Π΄Π²Π΅ посСбни Π΄Π΅Ρ˜ΡΡ‚Π²Π°. Π‘ΠΈΡ‚Π΅ Ρ„ΠΈΠ»ΠΎΠ·ΠΎΡ„ΠΈ ΠΌΠΎΠ»Ρ‡Π°Ρ‚. Π—Π°Π΄Π°Ρ‡Π°Ρ‚Π° Π΅ Π΄Π° сС најдС Ρ‚Π°ΠΊΠΎΠ² Π°Π»Π³ΠΎΡ€ΠΈΡ‚Π°ΠΌ ΡˆΡ‚ΠΎ ситС Π±ΠΈ размислувалС ΠΈ Π±ΠΈ Π±ΠΈΠ»Π΅ ΠΏΠΎΠ»Π½ΠΈ ΠΈ ΠΏΠΎ 54 Π³ΠΎΠ΄ΠΈΠ½ΠΈ.

ΠŸΡ€Π²ΠΎ, Π΄Π° сС ΠΎΠ±ΠΈΠ΄Π΅ΠΌΠ΅ Π΄Π° Π³ΠΎ Ρ€Π΅ΡˆΠΈΠΌΠ΅ овој ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ ΠΏΡ€Π΅ΠΊΡƒ ΠΊΠΎΡ€ΠΈΡΡ‚Π΅ΡšΠ΅ Π½Π° Π·Π°Π΅Π΄Π½ΠΈΡ‡ΠΊΠΈ простор. Π’ΠΈΠ»ΡƒΡˆΠΊΠΈΡ‚Π΅ Π»Π΅ΠΆΠ°Ρ‚ Π½Π° Π·Π°Π΅Π΄Π½ΠΈΡ‡ΠΊΠ°Ρ‚Π° маса ΠΈ Ρ„ΠΈΠ»ΠΎΠ·ΠΎΡ„ΠΈΡ‚Π΅ Сдноставно Π³ΠΈ Π·Π΅ΠΌΠ°Π°Ρ‚ ΠΊΠΎΠ³Π° сС ΠΈ Π³ΠΈ Π²Ρ€Π°ΡœΠ°Π°Ρ‚ Π½Π°Π·Π°Π΄. Π’ΡƒΠΊΠ° ΠΈΠΌΠ° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΈ со ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡ˜Π°Ρ‚Π°, ΠΊΠΎΠ³Π° Ρ‚ΠΎΡ‡Π½ΠΎ Π΄Π° Π·Π΅ΠΌΠ°ΠΌ surebets? ΡˆΡ‚ΠΎ Π°ΠΊΠΎ Π½Π΅ΠΌΠ° Π²ΠΈΠ»ΡƒΡˆΠΊΠ°? Но, ΠΏΡ€Π²ΠΎ, Π΄Π° ΠΏΠΎΡ‡Π½Π΅ΠΌΠ΅ со Ρ„ΠΈΠ»ΠΎΠ·ΠΎΡ„ΠΈΡ‚Π΅.

Π—Π° Π΄Π° Π·Π°ΠΏΠΎΡ‡Π½Π΅ΠΌΠ΅ нишки, користимС Π±Π°Π·Π΅Π½ со нишки 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 ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈΡ€Π°ΡšΠ΅

На сликата, Π±Π»ΠΎΠΊΠΈΡ€Π°ΡšΠ΅ Π½Π° нишки (ΡœΠΎΡ€-сокак). Π—Π΅Π»Π΅Π½Π° - ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π°ΡšΠ΅, Ρ†Ρ€Π²Π΅Π½Π° - ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡ˜Π°, сива - Π½ΠΈΡˆΠΊΠ°Ρ‚Π° спиС. Π ΠΎΠΌΠ±ΠΈΡ‚Π΅ Π³ΠΎ ΠΎΠ·Π½Π°Ρ‡ΡƒΠ²Π°Π°Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Ρ‚ΠΎ Π½Π° Π·Π°ΠΏΠΎΡ‡Π½ΡƒΠ²Π°ΡšΠ΅ Π½Π° 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 ΠΏΠ°Ρ‚ΠΈ ΠΏΠΎΠΌΠ°Π»ΠΊΡƒ ΠΎΠ΄ Π»ΠΎΡˆΠΈΡ‚Π΅. Π—Π½Π°Ρ‡ΠΈ, ΠΌΠ°Π»Π° Π³Ρ€Π΅ΡˆΠΊΠ° Π²ΠΎ ΠΊΠΎΠ΄ΠΎΡ‚ Π΄ΠΎΠ²Π΅Π΄ΡƒΠ²Π° Π΄ΠΎ ΠΏΠ°Π΄ Π½Π° пСрформанситС. Π’ΡƒΠΊΠ°, исто Ρ‚Π°ΠΊΠ°, Π²Ρ€Π΅Π΄ΠΈ Π΄Π° сС Π½Π°ΠΏΠΎΠΌΠ΅Π½Π΅ Π΄Π΅ΠΊΠ° Π΅ ΠΌΠΎΠΆΠ½Π° Ρ€Π΅Ρ‚ΠΊΠ° ΡΠΈΡ‚ΡƒΠ°Ρ†ΠΈΡ˜Π° ΠΊΠΎΠ³Π° ситС Ρ„ΠΈΠ»ΠΎΠ·ΠΎΡ„ΠΈ ја Π·Π΅ΠΌΠ°Π°Ρ‚ Π»Π΅Π²Π°Ρ‚Π° Π²ΠΈΠ»ΡƒΡˆΠΊΠ°, Π½Π΅ΠΌΠ° дСсна, ја ставаат Π»Π΅Π²Π°Ρ‚Π°, Ρ‡Π΅ΠΊΠ°Π°Ρ‚, ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ ја Π·Π΅ΠΌΠ°Π°Ρ‚ Π»Π΅Π²Π°Ρ‚Π°, ΠΈΡ‚Π½. Оваа ΡΠΈΡ‚ΡƒΠ°Ρ†ΠΈΡ˜Π° Π΅ исто Ρ‚Π°ΠΊΠ° Π³Π»Π°Π΄ΡƒΠ²Π°ΡšΠ΅, повСќС ΠΊΠ°ΠΊΠΎ ΡœΠΎΡ€-сокак. НС успСав Π΄Π° Π³ΠΎ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π°ΠΌ. ΠŸΠΎΠ΄ΠΎΠ»Ρƒ Π΅ слика Π·Π° ΡΠΈΡ‚ΡƒΠ°Ρ†ΠΈΡ˜Π° ΠΊΠΎΠ³Π° Π΄Π²Π°Ρ˜Ρ†Π° лоши Ρ„ΠΈΠ»ΠΎΠ·ΠΎΡ„ΠΈ Π³ΠΈ Π·Π΅Π»Π΅ Π΄Π²Π΅Ρ‚Π΅ Π²ΠΈΠ»ΡƒΡˆΠΊΠΈ, Π° Π΄Π²Π°Ρ˜Ρ†Π° Π΄ΠΎΠ±Ρ€ΠΈ Π³Π»Π°Π΄ΡƒΠ²Π°Π°Ρ‚.

Π”ΠΎΠ±Ρ€ΠΎ Π½Π°Ρ…Ρ€Π°Π½Π΅Ρ‚ΠΈ Ρ„ΠΈΠ»ΠΎΠ·ΠΎΡ„ΠΈ ΠΈΠ»ΠΈ ΠΊΠΎΠ½ΠΊΡƒΡ€Π΅Π½Ρ‚Π½ΠΎ .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 (mutex), Π½ΠΎ со ΠΏΠΎΠ΄Π΄Ρ€ΡˆΠΊΠ° Π·Π° Ρ‡Π΅ΠΊΠ°ΡšΠ΅ Π²ΠΎ циклус, Ρ€Π΅ΠΊΡƒΡ€Π·ΠΈΡ˜Π°, ΠΌΠΎΠ΄Π΅Π»ΠΎΡ‚ Condition Variable (повСќС Π·Π° Ρ‚ΠΎΠ° ΠΏΠΎΠ΄ΠΎΠ»Ρƒ), ΠΈΡ‚Π½. АјдС Π΄Π° ΠΏΠΎΠ³Π»Π΅Π΄Π½Π΅ΠΌΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ со Π½Π΅Π³ΠΎ.

// БпрячСм ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ для ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€Π° ΠΎΡ‚ всСх, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±Π΅Π· Π΄Π΅Π΄Π»ΠΎΠΊΠΎΠ².
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), ΠΊΠΎΠΈ сС присутни Π²ΠΎ ситС ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚ΠΈ. Π—Π°Ρ‚ΠΎΠ°, Π°ΠΊΠΎ сС ΠΈΠ·Π±Π΅Ρ€Π΅ нСсоодвСтСн ΠΎΠ±Ρ˜Π΅ΠΊΡ‚, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ лСсно Π΄Π° Π΄ΠΎΠ±ΠΈΠ΅Ρ‚Π΅ ΡœΠΎΡ€-сокак (Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π°ΠΊΠΎ Π·Π°ΠΊΠ»ΡƒΡ‡ΠΈΡ‚Π΅ Π½Π° ΠΈΠ½Ρ‚Π΅Ρ€Π½ΠΈΡ€Π°Π½ стринг). Π—Π° ΠΎΠ²Π° Π³ΠΎ користимС сСкогаш скриСниот ΠΎΠ±Ρ˜Π΅ΠΊΡ‚.

ΠœΠΎΠ΄Π΅Π»ΠΎΡ‚ Condition Variable Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡƒΠ²Π° ΠΏΠΎΠΊΠΎΠ½Ρ†ΠΈΠ·Π½ΠΎ Π΄Π° Π³ΠΈ спровСдСтС ΠΎΡ‡Π΅ΠΊΡƒΠ²Π°ΡšΠ°Ρ‚Π° Π·Π° нСкоја слоТСна ΡΠΎΡΡ‚ΠΎΡ˜Π±Π°. Π’ΠΎ .НЕВ Π΅ нСцСлосно спорСд ΠΌΠ΅Π½Π΅ Π·Π°Ρ‚ΠΎΠ° ΡˆΡ‚ΠΎ Π²ΠΎ Ρ‚Π΅ΠΎΡ€ΠΈΡ˜Π°, Ρ‚Ρ€Π΅Π±Π° Π΄Π° ΠΈΠΌΠ° Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ Ρ€Π΅Π΄ΠΈΡ†ΠΈ Π½Π° Π½Π΅ΠΊΠΎΠ»ΠΊΡƒ ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ (ΠΊΠ°ΠΊΠΎ Π²ΠΎ Posix Threads), Π° Π½Π΅ Π½Π° Π΅Π΄Π΅Π½ lok. Вогаш ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π½Π°ΠΏΡ€Π°Π²Π°Ρ‚ Π·Π° ситС Ρ„ΠΈΠ»ΠΎΠ·ΠΎΡ„ΠΈ. Но, Π΄ΡƒΡ€ΠΈ ΠΈ Π²ΠΎ ΠΎΠ²Π°Π° Ρ„ΠΎΡ€ΠΌΠ°, Ρ‚ΠΎΠ° Π²ΠΈ ΠΎΠ²ΠΎΠ·ΠΌΠΎΠΆΡƒΠ²Π° Π΄Π° Π³ΠΎ Π½Π°ΠΌΠ°Π»ΠΈΡ‚Π΅ ΠΊΠΎΠ΄ΠΎΡ‚.

ΠΌΠ½ΠΎΠ³Ρƒ Ρ„ΠΈΠ»ΠΎΠ·ΠΎΡ„ΠΈ ΠΈΠ»ΠΈ async / await

Π”ΠΎΠ±Ρ€ΠΎ, сСга ΠΌΠΎΠΆΠ΅ΠΌΠ΅ Π΅Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎ Π΄Π° Π³ΠΈ Π±Π»ΠΎΠΊΠΈΡ€Π°ΠΌΠ΅ Π½ΠΈΡˆΠΊΠΈΡ‚Π΅. Но, ΡˆΡ‚ΠΎ Π°ΠΊΠΎ ΠΈΠΌΠ°ΠΌΠ΅ ΠΌΠ½ΠΎΠ³Ρƒ Ρ„ΠΈΠ»ΠΎΠ·ΠΎΡ„ΠΈ? 100? 10000? На ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π΄ΠΎΠ±ΠΈΠ²ΠΌΠ΅ 100000 Π±Π°Ρ€Π°ΡšΠ° Π΄ΠΎ Π²Π΅Π±-сСрвСрот. ЌС Π±ΠΈΠ΄Π΅ ΠΏΡ€Π΅ΠΊΡƒ Π³Π»Π°Π²Π° Π΄Π° сС создадС нишка Π·Π° сСкоС Π±Π°Ρ€Π°ΡšΠ΅, бидСјќи Ρ‚ΠΎΠ»ΠΊΡƒ ΠΌΠ½ΠΎΠ³Ρƒ нишки Π½Π΅ΠΌΠ° Π΄Π° сС ΠΎΠ΄Π²ΠΈΠ²Π°Π°Ρ‚ ΠΏΠ°Ρ€Π°Π»Π΅Π»Π½ΠΎ. ЌС Ρ€Π°Π±ΠΎΡ‚ΠΈ само ΠΎΠ½ΠΎΠ»ΠΊΡƒ ΠΊΠΎΠ»ΠΊΡƒ ΡˆΡ‚ΠΎ ΠΈΠΌΠ° Π»ΠΎΠ³ΠΈΡ‡ΠΊΠΈ Ρ˜Π°Π΄Ρ€Π° (ΠΈΠΌΠ°ΠΌ 4). А ситС останати само ќС ΠΎΠ΄Π·Π΅ΠΌΠ°Ρ‚ рСсурси. Π•Π΄Π½ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π·Π° овој ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ Π΅ ΡˆΠ΅ΠΌΠ°Ρ‚Π° Π·Π° Π°ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡ˜Π° / Ρ‡Π΅ΠΊΠ°ΡšΠ΅. НСговата идСја Π΅ Π΄Π΅ΠΊΠ° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡ˜Π°Ρ‚Π° Π½Π΅ ја Π΄Ρ€ΠΆΠΈ Π½ΠΈΡˆΠΊΠ°Ρ‚Π° Π°ΠΊΠΎ Ρ‚Ρ€Π΅Π±Π° Π΄Π° Ρ‡Π΅ΠΊΠ° Π½Π΅ΡˆΡ‚ΠΎ Π΄Π° ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈ. И ΠΊΠΎΠ³Π° ΠΏΡ€Π°Π²ΠΈ Π½Π΅ΡˆΡ‚ΠΎ, ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΡƒΠ²Π° Π΄Π° сС ΠΈΠ·Π²Ρ€ΡˆΡƒΠ²Π° (Π½ΠΎ Π½Π΅ ΠΌΠΎΡ€Π° Π΄Π° Π±ΠΈΠ΄Π΅ Π½Π° истата нишка!). Π’ΠΎ Π½Π°ΡˆΠΈΠΎΡ‚ ΡΠ»ΡƒΡ‡Π°Ρ˜, ќС ја Ρ‡Π΅ΠΊΠ°ΠΌΠ΅ Π²ΠΈΠ»ΡƒΡˆΠΊΠ°Ρ‚Π°.

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 сСкунди. ΠŸΡ€Π΅Ρ‚Ρ…ΠΎΠ΄Π½ΠΎΡ‚ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ со ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ Π³ΠΈ истрча само ΠΏΡ€Π²ΠΈΡ‚Π΅ 4 нишки, Π° останатитС Π²ΠΎΠΎΠΏΡˆΡ‚ΠΎ Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π΅Π°. БСкоја ΠΎΠ΄ ΠΎΠ²ΠΈΠ΅ 4 нишки бСшС Π²ΠΎ ΠΌΠΈΡ€ΡƒΠ²Π°ΡšΠ΅ ΠΎΠΊΠΎΠ»Ρƒ 2 ms. И Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π·Π° Π°ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€Π°ΡšΠ΅ / Ρ‡Π΅ΠΊΠ°ΡšΠ΅ Ρ€Π°Π±ΠΎΡ‚ΠΈ Π½Π° ситС 100, со просСчно Ρ‡Π΅ΠΊΠ°ΡšΠ΅ ΠΎΠ΄ 6.8 сСкунди сСкоС. Π‘Π΅ Ρ€Π°Π·Π±ΠΈΡ€Π°, Π²ΠΎ Ρ€Π΅Π°Π»Π½ΠΈΡ‚Π΅ систСми, ΠΌΠΈΡ€ΡƒΠ²Π°ΡšΠ΅ 6 сСкунди Π΅ Π½Π΅ΠΏΡ€ΠΈΡ„Π°Ρ‚Π»ΠΈΠ²ΠΎ ΠΈ ΠΏΠΎΠ΄ΠΎΠ±Ρ€ΠΎ Π΅ Π΄Π° Π½Π΅ сС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΡƒΠ²Π°Π°Ρ‚ Ρ‚ΠΎΠ»ΠΊΡƒ ΠΌΠ½ΠΎΠ³Ρƒ Π±Π°Ρ€Π°ΡšΠ° ΠΊΠ°ΠΊΠΎ ΠΎΠ²Π°. Π Π΅ΡˆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ со ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ сС ΠΏΠΎΠΊΠ°ΠΆΠ° Π΄Π΅ΠΊΠ° Π²ΠΎΠΎΠΏΡˆΡ‚ΠΎ Π½Π΅ Π΅ скалабилно.

Π—Π°ΠΊΠ»ΡƒΡ‡ΠΎΠΊ

Како ΡˆΡ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅ ΠΎΠ΄ ΠΎΠ²ΠΈΠ΅ ΠΌΠ°Π»ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ, .NET ΠΏΠΎΠ΄Π΄Ρ€ΠΆΡƒΠ²Π° ΠΌΠ½ΠΎΠ³Ρƒ конструкции Π·Π° ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡ˜Π°. Π‘Π΅ΠΏΠ°ΠΊ, Π½Π΅ Π΅ сСкогаш ΠΎΡ‡ΠΈΠ³Π»Π΅Π΄Π½ΠΎ ΠΊΠ°ΠΊΠΎ Π΄Π° Π³ΠΈ користитС. Π‘Π΅ Π½Π°Π΄Π΅Π²Π°ΠΌ Π΄Π΅ΠΊΠ° овој напис бСшС корисСн. ЗасСга, ΠΎΠ²Π° Π΅ ΠΊΡ€Π°Ρ˜ΠΎΡ‚, Π½ΠΎ останаа ΡƒΡˆΡ‚Π΅ ΠΌΠ½ΠΎΠ³Ρƒ интСрСсни Ρ€Π°Π±ΠΎΡ‚ΠΈ, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€, нишки Π·Π±ΠΈΡ€ΠΊΠΈ, TPL Dataflow, Reactive programming, Software Transaction model ΠΈΡ‚Π½.

Π˜Π·Π²ΠΎΡ€ΠΈ

Π˜Π·Π²ΠΎΡ€: www.habr.com

Π”ΠΎΠ΄Π°Π΄Π΅Ρ‚Π΅ ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€