แแแแฎแแ, แ แแแแ แแฃแจแแแแก แแแแแฃแ แแแขแฃแแ แแ แแแ แแแแแฃแ แ แแ แแแ แแแแ แแแ .Net-แจแ, แแแแแแแแแ แคแแแแกแแคแแกแแ แกแแกแแแแแ แแ แแแแแแแก แแแแแงแแแแแแ. แแแแแ แแกแแแแ, แซแแคแแแแก/แแ แแชแแกแแแแก แกแแแฅแ แแแแแแชแแแกแแแ, แแฅแขแแ แแก แแแแแแแแแ (แจแแแแแ แแแฌแแแแแจแ). แกแขแแขแแ แจแแแซแแแแ แกแแกแแ แแแแแ แแงแแก แแแ แแแแ แแแชแแแแแกแแแแก แแ แแฅแแแแ แชแแแแแก แแแแแฎแแแแแกแแแแก.
แ แแขแแ แแแแแแ แกแแแ แแแ? แขแ แแแแแกแขแแ แแแ แแแแฆแฌแแแแ แแแแแแแแฃแ แแแแแก, แแฃแ แแก แแแแแแ แแแงแแ แแแ แกแแแแแแแก แกแแฉแฅแแ แแก แจแแแฆแฃแแแแก แแ แแแแขแแ แจแแแแแจแแแแ แ แแชแฎแแแก แแ แแ, แจแแแซแแแแ แแแขแ แขแ แแแแแกแขแแ แแก แแแแแแแแแ. แแแแแแ แแฃแแแ, แแแแแชแแแแ แ แแแแแแแแ แแแ แแแแ แแ แแแแฎแแแ แแแแแแ แกแแกแขแแแแแแกแแแ แแงแแกแแแ แแแกแฃแฎแก แแแแแ. แแกแแ แกแแขแฃแแชแแแจแ โแแแ แแแแฃแ แโ แแ แแแ แแแแ แแแ, แ แแชแ แแแแฅแแก แแ แแ แจแแแกแ แฃแแแแแแ แแแแ, แแฆแแ แแ แแก แแคแแฅแขแฃแ แ. แแฅแแแ แฃแแแ แ แแแแ แแ แแแแแญแ แแ แแ แแแ แแฃแแ แแ แแ แแแ แแฃแแ แจแแกแ แฃแแแแแก แแ แแแแแแ. แฃแคแ แ แแแขแแช, แแก แแ แแแแแแ แแ แกแแแแแก แกแฎแแแแแกแฎแแ แแแแแแ: แซแแคแแแแก แแแแแแ, แแ แแชแแกแแแแก แแแแแแ, แฅแกแแแจแ แแ แกแแแฃแแ แแแแฅแแแแแแก แแแแแแ (แแแแแฌแแแแแฃแแ แกแแกแขแแแแแ). .NET-แก แแฅแแก แแแฆแแแ แฎแแ แแกแฎแแก, แแ แแจแ แแแแแชแแแแ แขแแฅแแแแแแแแแ แแกแแแ แแ แแแแแแแแแก แกแฌแ แแคแแ แแ แแคแแฅแขแฃแ แแ แแแแแญแ แแกแแแแก.
แแแแแแแแ
Edsger Dijkstra-แ แแก แแ แแแแแแ แแแแแก แกแขแฃแแแแขแแแก แฏแแ แแแแแ 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 แฅแแแแก แแ แจแแแก แซแแคแแแก แแ แแแแชแแแแแแก แ แแแแแแแแแก แแแฎแแแแแ. แแ แแ แแฃแแ แงแแแแ AppDomain-แแกแแแแก. แแก แแฃแแ แฃแแแ แแฅแแแก แแแแแงแแแแแฃแแ แแแแฅแแแก แงแแแแแแแแก, แ แแแแแ. แแ แแ แแก แกแแญแแ แ แแแแแแแก แจแแฅแแแ, แฌแแจแแ, แแแแ แ แแแแแ แแ แ.แจ. 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.
แคแแแฃแ แแจแ, แซแแคแแแแก แแแแแแ แแแ (แฉแแฎแ). แแฌแแแแ - แจแแกแ แฃแแแแ, แฌแแแแแ - แกแแแฅแ แแแแแแชแแ, แแแชแ แแกแคแแ แ - แซแแคแ แกแซแแแแแก. แ แแแแแแ แแแฃแแแแแแก แแแแชแแแแแแก แแแฌแงแแแแก แแ แแก.
แคแแแแกแแคแแกแแ แจแแแจแแแ
แแแ แแแแแ แแ แแ แแก แกแแญแแ แ แแแแกแแแฃแแ แแแแ แแแแ แ แกแแแแแแแก แคแแฅแ แ, แแแแ แแ แจแแแจแแแ แแแแแกแแแแ แก แแแซแฃแแแแก แคแแแแกแแคแแแแ แฃแแ แ แแฅแแแก. แจแแแแชแแแแ แฉแแแแก แแ แแแแแแแจแ แซแแคแแแแก แจแแแจแแแแก แกแแขแฃแแชแแแก แกแแแฃแแแชแแ. แจแแแจแแแ แแ แแก, แ แแแแกแแช แซแแคแ แขแ แแแแแแก, แแแแ แแ แแแแจแแแแแแแแแ แกแแแฃแจแแแก แแแ แแจแ, แกแฎแแ แกแแขแงแแแแแ แ แแ แแแฅแแแ, แแก แแแแแ แฉแแฎแแ, แแฎแแแแ แแฎแแ แซแแคแ แแ แกแซแแแแแก, แแ แแแแ แแฅแขแแฃแ แแ แแซแแแก แกแแญแแแแก, แแแแ แแ แกแแแแแแ แแ แแ แแก. แฎแจแแ แ แแแแแแแแแก แแแแแแแ แแกแแชแแแแแแแ แฉแแแแแแก แฃแแแ แแแแแแ แฃแแแแ แแฃ แแแแ แแก แแแ แแแแฆแแแ.
// ะขะพ ะถะต ััะพ ะธ ะฒ 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-แฏแแ แแแแแแแก แญแแแแ, แแแแ แ แชแฃแแ. แแกแ แ แแ, แแแแจแ แแชแแ แ แจแแชแแแแ แแฌแแแแก แจแแกแ แฃแแแแแก แแแ แแแแก. แแฅแแ แแฆแกแแแแจแแแแแ แแกแแช, แ แแ แแจแแแแแ แกแแขแฃแแชแแแ แจแแกแแซแแแแแแ, แ แแชแ แงแแแแ แคแแแแกแแคแแกแ แแแฆแแแก แแแ แชแฎแแแ แฉแแแแแก, แแ แแ แแก แแแ แฏแแแแ, แแงแแแแแแ แแแ แชแฎแแแ, แแแแแแแแแ, แแกแแ แแแฆแแแแ แแแ แชแฎแแแ แแ แ.แจ. แแก แกแแขแฃแแชแแแช แจแแแจแแแแ, แฃแคแ แ แฉแแฎแก แฐแแแแก. แแแ แแแแแแแแ แ. แฅแแแแแ แแแชแแแฃแแแ แกแฃแ แแแ แกแแขแฃแแชแแแกแแแแก, แ แแแแกแแช แแ แแ แชแฃแแแ แคแแแแกแแคแแกแแ แแ แแแ แฉแแแแแแ แแแฆแ แแ แแ แ แแแ แแ แจแแแจแแแแแก.
แแฅ แฎแแแแแ, แ แแ แซแแคแแแ แแฆแแแซแแแแ แฎแแแแ แแ แชแแแแแแแ แ แแกแฃแ แกแแก แแแแแแแแแก. แแแฎแ แแแ แแแแแแ แแ แ แแ แแคแแ แก แแแแแแแก (แแฌแแแแ แแแแแ แแแ แแแแแ).
แคแแแแกแแคแแกแแก แกแแแแแแแ
แแแแแ แแ แแ แแ แแแแแแ, แ แแแแช แจแแแซแแแแ แจแแแคแแ แฎแแก แคแแแแกแแคแแกแแแแก แแแแแแฃแแ แแแฎแจแแแ, แแ แแก แแก, แแฃ แแ แ-แแ แแ แแแแแแแ แแแฃแแแแแแแแ แแแแแแแแ แฉแแแแแแแแ แฎแแแจแ (แแ แแกแแแ แแแก แแกแ แแแแ แซแแแแแแ). แแแ แ แแแแแแแแแ แแแแฉแแก แแแ แแจแ แแแ แฉแแแแแ. แแ แจแแแแฎแแแแแกแแแแก แจแแแแซแแแแ แแแแแ แแแแคแแฅแ แแ แแแแแก แแแแแแแแ, แแแแแแแแแ, แแก แแแแแแแแ 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
(แ แแแแแแช แแฅ แแแแแแงแแแแแ). แแฎแแ แแแ แแชแแก แ แแแแ แแแแแแแแก แแแแแแแแแแแแ, แแแแซแแแแก แชแแขแ แแ แกแฎแแ. แแแแแแแ, แงแแแแแคแแ แก แแแแแแแก แแแขแแแแแแชแแแกแแแแก. แแแแ แแ แฃแแแ แแแแฎแกแแแแแก, แ แแ แแก แแ แแก แแแแแ แแฅแขแแฃแ แ แชแแแแ, แ แแแแแแช แญแแแก แแ แแชแแกแแ แแก แ แแกแฃแ แกแแแก แแ แแแแ แฉแฃแแแแก แแแแแแก, แ แแแแช แจแแแซแแแแ แแแแแแฌแแแแก แจแแแจแแแ, แแฃ แ แแแแแแแ แคแแแแกแแคแแกแ แแแฎแแแแ แฃแคแ แ แแ แแแ แแขแแขแฃแแ แแแแ แ แกแฎแแแแ, แแแแ แแ แแ แแฅแแแแ แแฅแ แแก แฉแแแแแแ (Priority Inversion-แแก แแ แแแแแแ) . แแแแขแแ, แฉแแแ แแแงแแแแแ แแแก แแฎแแแแ แกแแแแแ แ แแแฎแกแแแ แแแแจแ แซแแแแแ แแแแแ แชแแแแแแแแแแกแแแแก, แงแแแแแแแแ แ แแแกแแแ แแฎแแ แแก แแแ แแแแก, แฉแแแแแฃแแ แกแแแแขแแแแก แแ แกแฎแแ แกแแฃแ แแ แแแแแแก แแแ แแจแ.
แฎแแขแแ แแแแกแแแแก SpinLock
. แแแแแแฃแแแแ แแแแฃแแแแแแ โแแแ แซแแแแโ แแฅแ แแก แฉแแแแแแแกแแแแก. แแ แแก แฌแแ แฃแแแขแแแแแแแแ - แคแแแฃแ แแจแ, แแ แฉแแฃแแ แขแแ แแขแแ แแ. แแแ แแแแแ แกแ แฃแแแ แแ แแ แแก แแแแแงแแแแแฃแแ: แแฎแแแแ แแแแฎแแแแแแ 2/3 แแ แแแฎแ แซแแคแแ.
แแฅ แแแแแ แแ แแ แแแแแกแแแแแ แแฅแแแแ แแฎแแแแ แแแแแงแแแแแ Interlocked.CompareExchange
แแแแแ แแฅแขแแฃแ แ แแแแแแแแแ, แ แแแแ แช แแแแแ แแแชแแแฃแ แแแแจแแ แแแฉแแแแแแ (แแจแแแ แ แคแแแแกแแคแแกแแแจแ), แแแแ แแ แแแแ, แ แแแแ แช แฃแแแ แแแฅแแ, แแแแ แแฃแแแ แจแแแซแแแแ แแแแแแฌแแแแก แแแแแแแแ.
on Interlocked
แฃแแแ แแฆแแแแจแแแก, แ แแ แแ แแ แกแแแแแก แแฎแแแแ CompareExchange
, แแ แแแแ แแขแแแฃแ แ แฌแแแแแฎแแแกแ แแ แฉแแฌแแ แแก แกแฎแแ แแแแแแแแแช. แแ แชแแแแแแแแก แแแแแแแ แแแแ, แแ แจแแแแฎแแแแแจแ, แแฃ แกแฎแแ แแแแแก แแฅแแก แแ แ, แ แแ แจแแแขแแแแก แชแแแแแแแแแ (แฌแแแแแแฎแแ 1, แฌแแแแแแฎแแ 2, แฉแแฌแแ แแ 2, แฉแแฌแแ แแ 1 แชแฃแแแ), แแก แจแแแซแแแแ แแแแแงแแแแแฃแ แแฅแแแก แแ แแ แแแแจแแแแแแแแก แแแแแแแฅแกแฃแ แ แชแแแแแแแแแแกแแแแก (Interlocked Anything pattern) .
แแแ แแแแก แ แแแแแแก แแแแแฌแงแแแขแแแแแแแ
แแแแกแแแแแก, แ แแ แแแแแแแ แแแแชแแแแ แ แแกแฃแ แกแแแแก แแแฎแแ แฏแแ แแแ แงแฃแแจแ, แแแแฎแแ, แ แแแแ แจแแแแแซแแแ แแแแแแแแก แแแแ. แกแฎแแ แกแแขแงแแแแแ แ แแ แแแฅแแแ, แแแแแแ แซแแแแ แฉแแแแ แแแแแแแแ, แแแแฎแแ, แ แแแแ แแซแแแแแก แแแแขแแแ แคแแแแกแแคแแกแก แแ แแฆแแแซแแแก แแแก แแฎแแแแ แกแแญแแ แแแแแก แจแแแแฎแแแแแจแ. แแแ แแแ แ แแแจแ, แแแแแ แจแแแฎแแแแ แ แแแแ แแแแแแแแแ แแก แแแแ แแชแแฃแแ แกแแกแขแแแแก แแแ แแแแก แ แแแแแจแ. แแฅ แงแแแแ แกแขแ แฃแฅแขแฃแ แ แฎแจแแ แแ แฃแคแ แ แแแแแ แแแแ แ แแแแฎแแแ แแแแแก แกแแแ แชแแจแ. แ แแแแแแฏแแ แแ แแแแ, แแแแแแแแแ AutoResetEvent
แจแแกแแซแแแ 53-แฏแแ แแแแ SpinLock
[แ แแฎแขแแ แ]. แแแแ แแ แแแแ แแแฎแแแ แแแแ แแฅแแแ แจแแแแซแแแแ แแ แแชแแกแแแแก แกแแแฅแ แแแแแแชแแ แแแแ แกแแกแขแแแแจแ, แแแ แแแแแ แแฃ แแ แ.
แซแแ แแแแแ แแแแกแขแ แฃแฅแชแแ แแฅ แแ แแก แกแแแแคแแ แ, แ แแแแแแช แจแแแแแแแแแแแฃแแแ แแแแกแขแ แแก แแแแ แแแฎแแแแ แ แกแแฃแแฃแแแก แฌแแ. แกแแแแคแแ แ, แแแ แขแแแแ แ แแ แแแฅแแแ, แแ แแก แแแแแแแแ แแแแแ แ แแชแฎแแ, แ แแแแแกแแช แแแ แแแแก แกแแกแขแแแ แแ แแแกแแ แแ แ แแแแ แแชแแ, แแ แแ แแ แจแแแชแแ แแแ. แแฃ แแก แแแ แจแแแชแแ แแ, แแฃแแแแแแ, แแแจแแ แแแ แแก แแแแ แแแแแแแแ. แ แแแแกแแช แ แแชแฎแแ แแแ แแแแ แกแฎแแ แแฅแขแแฃแ แ แซแแคแแ/แแ แแชแแกแแ, แแแจแแ แซแแคแแแ แแแแแขแแแแแฃแแแ แแ แกแแแแคแแ แ แแแแแ แแชแแ แแแแ แแแแแแแ แ แแชแฎแแแ. แจแแแซแแแแ แฌแแ แแแแแแแแแแ แแแขแแ แแแแแแ แแแกแขแแแฃแแจแ แกแแแแคแแ แแแ. .NET แแแแแแแแแ แ แแแแแแแแ แแแแกแขแ แฃแฅแชแแแก แแกแแแแกแ แคแฃแแฅแชแแแแแ แแแแ: AutoResetEvent
, ManualResetEvent
, Mutex
แแ แแ แแ Semaphore
. แฉแแแ แแแแแแแงแแแแแ AutoResetEvent
, แแก แแ แแก แแ แแแแกแขแ แฃแฅแชแแแแแแแ แฃแแแ แขแแแแกแ: แแฎแแแแ แแ แ แแแแจแแแแแแแ 0 แแ 1 (false, true). แแแกแ แแแแแแ WaitOne()
แแแแแแแก แแแแแซแแฎแแแแก แแแแแก, แแฃ แแแแจแแแแแแแ แแงแ 0, แฎแแแ แแฃ 1, แแแชแแ แแแก แแแก 0-แแแ แแ แแแแแขแแแแแก แแแก. แแแแแแ Set()
แแฌแแแก 1-แแแ แแ แฃแจแแแแก แแ แ แแแแขแแแก, แ แแแแแแช แแกแแ 0-แแแ แแแแแ. แแแฅแแแแแแก แ แแแแ แช แแแขแ แแก แขแฃแ แแแแ.
แแแแแ แแแแแ แแฃแแแ แแแแแกแแแแแ แแ แแแแแแแงแแแแ แกแแแแขแ แแแแแแฃแแ แคแแแแกแแคแแกแแกแแแแก แแ แแ แ แแ แแแ แแฃแแแ. แแแแ. แแฎแแ แจแแแซแแแแ แ แแแแแแแแ แคแแแแกแแคแแกแ แแงแแก แแ แแแ แแฃแแแ แแ แแ แ แแ แแ. แแแแ แแ แฉแแแ แแแแแ แแแแแแแแ แแแแแแแแ แฌแแแแแแก, แ แแแ แกแฌแแ แแ, แแแแแแแ แแแแชแแแแ แ แแแแ (แ แแแแแก แแแ แแแแแ), แแแแฆแแ surebets.
// ะะปั ะฑะปะพะบะธัะพะฒะฐะฝะธั ะพัะดะตะปัะฝะพะณะพ ัะธะปะพัะพัะฐ.
// ะะฝะธัะธะฐะปะธะทะธััะตััั: 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 แแแแฃแจแ แกแแจแฃแแแแแแก แแแซแแแแ แฃแคแ แ แแแแแแ แแแแแฎแแ แชแแแแแ แ แแแแ แ แแฃแแ แแแแแแแ แแแแแก แแแแแแแแ. .NET-แจแ แแก แแ แแกแ แฃแแแ, แฉแแแ แแแ แแ, แแแแขแแ แแแแ แแฃแแแ, แฃแแแ แแงแแก แ แแแแแแแแ แ แแแ แ แแแแแแแแ แชแแแแแแ (แ แแแแ แช Posix Threads-แจแ), แแ แแ แ แแ แ แแแแแ. แแแจแแ แจแแแซแแแแ แแแแ แแแแแแแแแ แงแแแแ แคแแแแกแแคแแกแแกแแแแก. แแแแ แแ แแ แคแแ แแแแแช แแ, แแก แกแแจแฃแแแแแแก แแแซแแแแ แจแแแแชแแ แแ แแแแ.
แแแแ แ แคแแแแกแแคแแกแ แแ 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 แแฎแแ แก แฃแญแแ แก แแ แแแแแ แกแแแฅแ แแแแแแชแแแก แแแแกแขแ แฃแฅแชแแแก. แแฃแแชแ, แงแแแแแแแแก แแ แแ แแก แแแแแแ, แแฃ แ แแแแ แแแแแแงแแแแ แแกแแแ. แแแแแ แแแฅแแก, แ แแ แแก แกแขแแขแแ แกแแกแแ แแแแแ แแงแ. แฏแแ แฏแแ แแแแ แแก แแแกแแกแ แฃแแแ, แแแแ แแ แแแแแ แแแแ แ แกแแแแขแแ แแกแ แ แแ แแแ แฉแ, แแแแแแแแแ, thread-safe แแแแแฅแชแแแแ, TPL Dataflow, Reactive programming, Software Transaction model แแ แ.แจ.
แแแคแแ แแแชแแแก แฌแงแแ แแแแ
- แแแแแแแก แแแแฃแแแแแแชแแ:
แแแแแฃแ แแแขแฃแแแแแก แแแแฃแแแแแแขแแ แ - MSDN:
แซแแคแแก ,แแกแแแฅแ แแแฃแแ แแ แแแ แแแแ แแแแก แจแแแแแแแแ แแ แแ แแแแแ แกแฎแแ แกแฎแแ - [Richter] - CLR C#-แแ, แฏแแคแ แ แ แแฎแขแแ แ
- [แแ แแ แแแแแ แขแ] -
แฉแแแแขแแแก แจแแกแแฎแแ แแแแแก แแแแ - แกแฃแ แแแ - "แชแแแแ แฎแแแแแก แจแแ แแก", แ.แกแแแแ แแแกแแ
แฌแงแแ แ: www.habr.com