เชเชพเชฒเซ เชเซเชเช เชเซ .Net เชฎเชพเช เชธเชฎเชตเชฐเซเชคเซ เช เชจเซ เชธเชฎเชพเชเชคเชฐ เชชเซเชฐเซเชเซเชฐเชพเชฎเชฟเชเช เชเซเชตเซ เชฐเซเชคเซ เชเชพเชฐเซเชฏ เชเชฐเซ เชเซ, เชเชฆเชพเชนเชฐเชฃ เชคเชฐเซเชเซ เชซเชฟเชฒเซเชธเซเชซเชฐเซเชธ เชกเชพเชเชจเชฟเชเช เชชเซเชฐเซเชฌเซเชฒเซเชฎเชจเซ เชเชชเชฏเซเช เชเชฐเซเชจเซ. เชฏเซเชเชจเชพ เช เชเซ, เชฅเซเชฐเซเชกเซ/เชชเซเชฐเชเซเชฐเชฟเชฏเชพเชเชจเชพ เชธเชฟเชเชเซเชฐเชจเชพเชเชเซเชถเชจเชฅเซ เชฒเชเชจเซ เช เชญเชฟเชจเซเชคเชพ เชฎเซเชกเซเชฒ เชธเซเชงเซ (เชจเซเชเซเชจเชพ เชญเชพเชเซเชฎเชพเช). เชฒเซเช เชชเซเชฐเชฅเชฎ เชชเชฐเชฟเชเชฟเชค เชฎเชพเชเซ เช เชฅเชตเชพ เชคเชฎเชพเชฐเชพ เชเซเชเชพเชจเชจเซ เชคเชพเชเซเช เชเชฐเชตเชพ เชฎเชพเชเซ เชเชชเชฏเซเชเซ เชฅเช เชถเชเซ เชเซ.
เชถเชพ เชฎเชพเชเซ เชคเซ เชฌเชฟเชฒเชเซเชฒ เชเชฐเชตเซเช? เชเซเชฐเชพเชเชเชฟเชธเซเชเชฐ เชคเซเชฎเชจเชพ เชฒเชเซเชคเซเชคเชฎ เชเชฆ เชธเซเชงเซ เชชเชนเซเชเชเซ เชเซ, เชฎเซเชฐเชจเซ เชเชพเชฏเชฆเซ เชชเซเชฐเชเชพเชถเชจเซ เชเชคเชฟเชจเซ เชฎเชฐเซเชฏเชพเชฆเชพ เชชเชฐ เชเชงเชพเชฐ เชฐเชพเชเซ เชเซ เช เชจเซ เชคเซเชฅเซ เชธเชเชเซเชฏเชพเชฎเชพเช เชตเชงเชพเชฐเซ เชเซเชตเชพ เชฎเชณเซ เชเซ, เชตเชงเซ เชเซเชฐเชพเชเชเชฟเชธเซเชเชฐ เชฌเชจเชพเชตเซ เชถเชเชพเชฏ เชเซ. เชคเซ เช เชธเชฎเชฏเซ, เชกเซเชเชพเชจเซ เชฎเชพเชคเซเชฐเชพ เชตเชงเซ เชฐเชนเซ เชเซ, เช เชจเซ เชตเชชเชฐเชพเชถเชเชฐเซเชคเชพเช เชธเชฟเชธเซเชเชฎเซเชธ เชคเชฐเชซเชฅเซ เชคเชพเชคเซเชเชพเชฒเชฟเช เชชเซเชฐเชคเชฟเชธเชพเชฆเชจเซ เช เชชเซเชเซเชทเชพ เชฐเชพเชเซ เชเซ. เชเชตเซ เชธเซเชฅเชฟเชคเชฟเชฎเชพเช, "เชธเชพเชฎเชพเชจเซเชฏ" เชชเซเชฐเซเชเซเชฐเชพเชฎเชฟเชเช, เชเซเชฏเชพเชฐเซ เชเชชเชฃเซ เชชเชพเชธเซ เชเช เช เชเชเซเชเชฟเชเซเชฏเซเชเซเชเช เชฅเซเชฐเซเชก เชนเซเชฏ เชเซ, เชคเซ เชนเชตเซ เช เชธเชฐเชเชพเชฐเช เชจเชฅเซ. เชคเชฎเชพเชฐเซ เชเซเชเช เชฐเซเชคเซ เชเช เชธเชพเชฅเซ เช เชฅเชตเชพ เชธเชนเชตเชฐเซเชคเซ เช เชฎเชฒเชจเซ เชธเชฎเชธเซเชฏเชพเชจเซ เชนเชฒ เชเชฐเชตเชพเชจเซ เชเชฐเซเชฐ เชเซ. เชคเชฆเซเชชเชฐเชพเชเชค, เช เชธเชฎเชธเซเชฏเชพ เชตเชฟเชตเชฟเชง เชธเซเชคเชฐเซ เช เชธเซเชคเชฟเชคเซเชตเชฎเชพเช เชเซ: เชฅเซเชฐเซเชกเซเชจเชพ เชธเซเชคเชฐเซ, เชชเซเชฐเชเซเชฐเชฟเชฏเชพเชเชจเชพ เชธเซเชคเชฐเซ, เชจเซเชเชตเชฐเซเชเชฎเชพเช เชฎเชถเซเชจเซเชจเชพ เชธเซเชคเชฐเซ (เชตเชฟเชคเชฐเชฟเชค เชธเชฟเชธเซเชเชฎเซ). เชเชตเซ เชธเชฎเชธเซเชฏเชพเชเชจเซ เชเชกเชชเชฅเซ เช เชจเซ เช เชธเชฐเชเชพเชฐเช เชฐเซเชคเซ เชเชเซเชฒเชตเชพ เชฎเชพเชเซ .NET เชชเชพเชธเซ เชเชเซเช-เชเซเชฃเชตเชคเซเชคเชพเชตเชพเชณเซ, เชธเชฎเชฏ-เชเชเชพเชธเชพเชฏเซเชฒ เชคเชเชจเซเชเซ เชเซ.
เชเชฆเซเชฆเซเชถ
เชเชกเซเชเชฐ เชกเชฟเชเชเซเชธเซเชเซเชฐเชพเช 1965เชจเซ เชถเชฐเซเชเชคเชฎเชพเช เช เชคเซเชฎเชจเชพ เชตเชฟเชฆเซเชฏเชพเชฐเซเชฅเซเช เชธเชฎเชเซเชท เช เชธเชฎเชธเซเชฏเชพ เชเชญเซ เชเชฐเซ เชนเชคเซ. เชธเซเชฅเชพเชชเชฟเชค เชซเซเชฐเซเชฎเซเชฏเซเชฒเซเชถเชจ เชจเซเชเซ เชฎเซเชเชฌ เชเซ. เชซเชฟเชฒเชธเซเชซเซเชจเซ เชเซเชเซเชเชธ (เชธเชพเชฎเชพเชจเซเชฏ เชฐเซเชคเซ เชชเชพเชเช) เชธเชเชเซเชฏเชพ เช เชจเซ เชเชพเชเชเซเชจเซ เชธเชฎเชพเชจ เชธเชเชเซเชฏเชพ เชเซ. เชคเซเช เชฐเชพเชเชจเซเชก เชเซเชฌเชฒ เชชเชฐ เชฌเซเชธเซ เชเซ, เชคเซเชฎเชจเซ เชตเชเซเชเซ เชเชพเชเชเซ. เชซเชฟเชฒเซเชธเซเชซเชฐเซ เชคเซเชฎเชจเชพ เช เชจเชเชค เชเซเชฐเชพเชเชจเซ เชชเซเชฒเซเชเชฎเชพเชเชฅเซ เชเชพเช เชถเชเซ เชเซ, เชตเชฟเชเชพเชฐเซ เชถเชเซ เชเซ เช เชฅเชตเชพ เชฐเชพเชน เชเซเช เชถเชเซ เชเซ. เชซเชฟเชฒเซเชธเซเชซเชฐเชจเซ เชเชพเชตเชพ เชฎเชพเชเซ, เชคเชฎเชพเชฐเซ เชฌเซ เชเชพเชเชเซ เชฒเซเชตเชพเชจเซ เชเชฐเซเชฐ เชเซ (เชเซเชฒเซเชฒเซ เชเช เชเชพเชเชเซ เชชเซเชฐเชฅเชฎ เชธเชพเชฅเซ เชตเชนเซเชเชเซ เชเซ). เชเชพเชเชเซ เชเชชเชพเชกเชตเซ เช เชจเซ เชจเซเชเซ เชฎเซเชเชตเซ เช เชฌเซ เช เชฒเช-เช เชฒเช เชเซเชฐเชฟเชฏเชพเช เชเซ. เชฌเชงเชพ เชซเชฟเชฒเชธเซเชซเซ เชฎเซเชจ เชเซ. เชเชพเชฐเซเชฏ เชเชตเซเช เช เชฒเซเชเซเชฐเชฟเชงเชฎ เชถเซเชงเชตเชพเชจเซเช เชเซ เชเซ เชคเซ เชฌเชงเชพ 54 เชตเชฐเซเชท เชชเชเซ เชชเชฃ เชตเชฟเชเชพเชฐเซ เช เชจเซ เชธเชเชชเซเชฐเซเชฃ เชนเชถเซ.
เชชเซเชฐเชฅเชฎ, เชเชพเชฒเซ เชตเชนเซเชเชเชพเชฏเซเชฒ เชเชเซเชฏเชพเชจเชพ เชเชชเชฏเซเช เชฆเซเชตเชพเชฐเชพ เช เชธเชฎเชธเซเชฏเชพเชจเซ เชนเชฒ เชเชฐเชตเชพเชจเซ เชชเซเชฐเชฏเชพเชธ เชเชฐเซเช. เชเชพเชเชเชพ เชธเชพเชฎเชพเชจเซเชฏ เชเซเชฌเชฒ เชชเชฐ เชชเชกเซเชฒเชพ เชนเซเชฏ เชเซ เช เชจเซ เชซเชฟเชฒเซเชธเซเชซเชฐเซ เชเซเชฏเชพเชฐเซ เชนเซเชฏ เชคเซเชฏเชพเชฐเซ เชคเซเชจเซ เชฒเช เชเชพเชฏ เชเซ เช เชจเซ เชชเชพเชเซเช เชฎเซเชเซ เชฆเซ เชเซ. เช เชนเซเช เชธเชฟเชเชเซเชฐเชจเชพเชเชเซเชถเชจ เชธเชพเชฅเซ เชธเชฎเชธเซเชฏเชพเช เชเซ, เชเซเชเซเชเชธ เชเซเชฏเชพเชฐเซ เชธเซเชฐเชฌเซเชเซเชธ เชฒเซเชตเชพ? เชเชพเชเชเซ เชจ เชนเซเชฏ เชคเซ เชถเซเช? เชตเชเซเชฐเซ. เชชเชฐเชเชคเซ เชชเชนเซเชฒเชพ, เชเชพเชฒเซ เชซเชฟเชฒเซเชธเซเชซเชฐเซ เชถเชฐเซ เชเชฐเซเช.
เชฅเซเชฐเซเชกเซ เชถเชฐเซ เชเชฐเชตเชพ เชฎเชพเชเซ, เช
เชฎเซ เชฅเซเชฐเซเชก เชชเซเชฒเชจเซ เชเชชเชฏเซเช เชเชฐเซเช เชเซเช Task.Run
เชชเชฆเซเชงเชคเชฟ:
var cancelTokenSource = new CancellationTokenSource();
Action<int> create = (i) => RunPhilosopher(i, cancelTokenSource.Token);
for (int i = 0; i < philosophersAmount; i++)
{
int icopy = i;
// ะะพะผะตััะธัั ะทะฐะดะฐัั ะฒ ะพัะตัะตะดั ะฟัะปะฐ ะฟะพัะพะบะพะฒ. ะะตัะพะด RunDeadlock ะฝะต ะทะฐะฟััะบะฐะตัััั
// ััะฐะทั, ะฐ ะถะดะตั ัะฒะพะตะณะพ ะฟะพัะพะบะฐ. ะัะธะฝั
ัะพะฝะฝัะน ะทะฐะฟััะบ.
philosophers[i] = Task.Run(() => create(icopy), cancelTokenSource.Token);
}
เชฅเซเชฐเซเชก เชชเซเชฒ เชฅเซเชฐเซเชก เชฌเชจเชพเชตเชตเชพ เช
เชจเซ เชเชพเชขเซ เชจเชพเชเชตเชพเชจเซ เชเชชเซเชเชฟเชฎเชพเชเช เชเชฐเชตเชพ เชฎเชพเชเซ เชฐเชเชพเชฏเซเชฒ เชเซ. เช เชชเซเชฒเชฎเชพเช เชเชพเชฐเซเชฏเซเชจเซ เชเชคเชพเชฐ เชเซ เช
เชจเซ CLR เช เชเชพเชฐเซเชฏเซเชจเซ เชธเชเชเซเชฏเชพเชจเชพ เชเชงเชพเชฐเซ เชฅเซเชฐเซเชกเซ เชฌเชจเชพเชตเซ เชเซ เช
เชฅเชตเชพ เชฆเซเชฐ เชเชฐเซ เชเซ. เชฌเชงเชพ AppDomains เชฎเชพเชเซ เชเช เชชเซเชฒ. เช เชชเซเชฒ เชฒเชเชญเช เชนเชเชฎเซเชถเชพ เชเชชเชฏเซเช เชเชฐเชตเซ เชเซเชเช, เชเชพเชฐเชฃ เชเซ. เชฅเซเชฐเซเชกเซ, เชคเซเชฎเชจเซ เชเชคเชพเชฐเซ เชตเชเซเชฐเซ เชฌเชจเชพเชตเชตเชพ, เชเชพเชขเซ เชจเชพเชเชตเชพเชฎเชพเช เชชเชฐเซเชถเชพเชจ เชฅเชตเชพเชจเซ เชเชฐเซเชฐ เชจเชฅเซ. เชคเซ เชชเซเชฒ เชตเชฟเชจเชพ เชถเชเซเชฏ เชเซ, เชชเชฐเชเชคเซ เชชเชเซ เชคเชฎเชพเชฐเซ เชคเซเชจเซ เชธเซเชงเซ เชเชชเชฏเซเช เชเชฐเชตเซ เชชเชกเชถเซ Thread
, เช เชเชตเชพ เชเชฟเชธเซเชธเชพเช เชฎเชพเชเซ เชเชชเชฏเซเชเซ เชเซ เชเซเชฏเชพเชฐเซ เชคเชฎเชพเชฐเซ เชฅเซเชฐเซเชกเชจเซ เชชเซเชฐเชพเชฅเชฎเชฟเชเชคเชพ เชฌเชฆเชฒเชตเชพเชจเซ เชเชฐเซเชฐ เชนเซเชฏ, เชเซเชฏเชพเชฐเซ เช
เชฎเชพเชฐเซ เชชเชพเชธเซ เชฒเชพเชเชฌเซ เชเชพเชฎเชเซเชฐเซ เชนเซเชฏ, เชซเซเชฐเชเซเชฐเชพเชเชจเซเชก เชฅเซเชฐเซเชก เชตเชเซเชฐเซ เชฎเชพเชเซ.
เชฌเซเชเชพ เชถเชฌเซเชฆเซ เชฎเชพเช, System.Threading.Tasks.Task
เชตเชฐเซเช เชธเชฎเชพเชจ เชเซ Thread
, เชชเชฐเชเชคเซ เชคเชฎเชพเชฎ เชชเซเชฐเชเชพเชฐเชจเซ เชธเชเชตเชกเชคเชพเช เชธเชพเชฅเซ: เช
เชจเซเชฏ เชเชพเชฐเซเชฏเซเชจเชพ เชฌเซเชฒเซเช เชชเชเซ เชเชพเชฐเซเชฏเชจเซ เชเชฒเชพเชตเชตเชพเชจเซ เชเซเชทเชฎเชคเชพ, เชคเซเชฎเชจเซ เชเชพเชฐเซเชฏเซเชฎเชพเชเชฅเซ เชชเชฐเชค เชเชฐเชตเชพ, เชคเซเชฎเชจเซ เช
เชจเซเชเซเชณ เชฐเซเชคเซ เชตเชฟเชเซเชทเซเชชเชฟเชค เชเชฐเชตเชพ เช
เชจเซ เชตเชงเซ. เชตเชเซเชฐเซ. เช
เชธเชฟเชเช/เชชเซเชฐเชคเซเชเซเชทเชพ เชฌเชพเชเชงเชเชพเชฎเซเชจเซ เชเซเชเซ เชเชชเชตเชพ เชฎเชพเชเซ เชคเซเชฎเชจเซ เชเชฐเซเชฐ เชเซ (เชเชพเชธเซเช-เชเชงเชพเชฐเชฟเชค เช
เชธเชฟเชเชเซเชฐเซเชจเชธ เชชเซเชเชฐเซเชจ, IO เชเชชเชฐเซเชถเชจเซเชธเชจเซ เชฐเชพเชน เชเซเชตเชพ เชฎเชพเชเซ เชธเชฟเชจเซเชเซเชเซเชเชฟเช เชธเซเชเชฐ). เช
เชฎเซ เช เชตเชฟเชถเซ เชชเชเซเชฅเซ เชตเชพเชค เชเชฐเซเชถเซเช.
CancelationTokenSource
เช
เชนเซเช เชคเซ เชเชฐเซเชฐเซ เชเซ เชเซเชฅเซ เชฅเซเชฐเซเชก เชเซเชฒเชฟเชเช เชฅเซเชฐเซเชกเชจเชพ เชธเชเชเซเชค เชชเชฐ เชชเซเชคเชพเชจเซ เชธเชฎเชพเชชเซเชค เชเชฐเซ เชถเชเซ.
เชธเชฎเชจเซเชตเชฏเชจ เชธเชฎเชธเซเชฏเชพเช
เช เชตเชฐเซเชงเชฟเชค เชซเชฟเชฒเซเชธเซเชซเชฐเซเชธ
เช เซเช เชเซ, เชเชชเชฃเซ เชเชพเชฃเซเช เชเซเช เชเซ เชฅเซเชฐเซเชกเซ เชเซเชตเซ เชฐเซเชคเซ เชฌเชจเชพเชตเชตเซ, เชเชพเชฒเซ เชฒเชเช เชเชฐเชตเชพเชจเซ เชชเซเชฐเชฏเชพเชธ เชเชฐเซเช:
// ะัะพ ะบะฐะบะธะต ะฒะธะปะบะธ ะฒะทัะป. ะ ะฟัะธะผะตัั: 1 1 3 3 - 1ะน ะธ 3ะน ะฒะทัะปะธ ะฟะตัะฒัะต ะดะฒะต ะฟะฐัั.
private int[] forks = Enumerable.Repeat(0, philosophersAmount).ToArray();
// ะขะพ ะถะต, ััะพ RunPhilosopher()
private void RunDeadlock(int i, CancellationToken token)
{
// ะะดะฐัั ะฒะธะปะบั, ะฒะทััั ะตั. ะญะบะฒะธะฒะฐะปะตะฝัะฝะพ:
// while(true)
// if forks[fork] == 0
// forks[fork] = i+1
// break
// Thread.Sleep() ะธะปะธ Yield() ะธะปะธ SpinWait()
void TakeFork(int fork) =>
SpinWait.SpinUntil(() =>
Interlocked.CompareExchange(ref forks[fork], i+1, 0) == 0);
// ะะปั ะฟัะพััะพัั, ะฝะพ ะผะพะถะฝะพ ั Interlocked.Exchange:
void PutFork(int fork) => forks[fork] = 0;
while (true)
{
TakeFork(Left(i));
TakeFork(Right(i));
eatenFood[i] = (eatenFood[i] + 1) % (int.MaxValue - 1);
PutFork(Left(i));
PutFork(Right(i));
Think(i);
// ะะฐะฒะตััะธัั ัะฐะฑะพัั ะฟะพ-ั
ะพัะพัะตะผั.
token.ThrowIfCancellationRequested();
}
}
เช
เชนเซเช เชเชชเชฃเซ เชชเชนเซเชฒเชพ เชกเชพเชฌเซ เชเชพเชเชเซ เชฒเซเชตเชพเชจเซ เชชเซเชฐเชฏเชคเซเชจ เชเชฐเซเช เชเซเช, เช
เชจเซ เชชเชเซ เชเชฎเชฃเซ เชเชพเชเชเซ, เช
เชจเซ เชเซ เชคเซ เชเชพเชฎ เชเชฐเซ เชเซ, เชคเซ เชชเชเซ เชเชชเชฃเซ เชเชพเชเช เชเซเช เช
เชจเซ เชคเซเชจเซ เชชเชพเชเซเช เชฎเซเชเซเช เชเซเช. เชเช เชเชพเชเชเซ เชฒเซเชตเซ เช เชชเชฐเชฎเชพเชฃเซ เชเซ, เชเชเชฒเซ เชเซ. เชฌเซ เชฅเซเชฐเซเชกเซ เชเช เช เชธเชฎเชฏเซ เชเช เชฒเช เชถเชเชคเชพ เชจเชฅเซ (เชเซเชเซ: เชชเซเชฐเชฅเชฎ เชตเชพเชเชเซ เชเซ เชเซ เชเชพเชเชเซ เชฎเชซเชค เชเซ, เชฌเซเชเซ - เชชเชฃ, เชชเซเชฐเชฅเชฎ เชฒเซ เชเซ, เชฌเซเชเซ เชฒเซ เชเซ). เช เชฎเชพเชเซ Interlocked.CompareExchange
, เชเซ เชชเซเชฐเซเชธเซเชธเชฐ เชธเซเชเชจเชพ เชธเชพเชฅเซ เช
เชฎเชฒเชฎเชพเช เชฎเซเชเชตเซเช เชเชตเชถเซเชฏเช เชเซ (TSL
, XCHG
), เชเซ เช
เชฃเซ เช
เชจเซเชเซเชฐเชฎเชฟเช เชตเชพเชเชเชจ เช
เชจเซ เชฒเซเชเชจ เชฎเชพเชเซ เชฎเซเชฎเชฐเซเชจเชพ เชเซเชเชกเชพเชจเซ เชคเชพเชณเซเช เชฎเชพเชฐเซ เชเซ. เช
เชจเซ SpinWait เช เชฌเชพเชเชงเชเชพเชฎเชจเซ เชธเชฎเชเชเซเชท เชเซ while(true)
เชฎเชพเชคเซเชฐ เชฅเซเชกเชพ "เชเชพเชฆเซ" เชธเชพเชฅเซ - เชฅเซเชฐเซเชก เชชเซเชฐเซเชธเซเชธเชฐ เชฒเซ เชเซ (Thread.SpinWait
), เชชเชฐเชเชคเซ เชเซเชเชฒเซเชเชตเชพเชฐ เช
เชจเซเชฏ เชฅเซเชฐเซเชก เชชเชฐ เชจเชฟเชฏเชเชคเซเชฐเชฃ เชธเซเชฅเชพเชจเชพเชเชคเชฐเชฟเชค เชเชฐเซ เชเซ (Thread.Yeild
) เช
เชฅเชตเชพ เชเชเชเซ เชเชพเชฏ เชเซ (Thread.Sleep
).
เชชเชฐเชเชคเซ เช เชเชเซเชฒ เชเชพเชฎ เชเชฐเชคเซเช เชจเชฅเซ, เชเชพเชฐเชฃ เชเซ เชตเชนเซเชคเซ เชเซเชเช เชธเชฎเชฏเชฎเชพเช (เชฎเชพเชฐเชพ เชฎเชพเชเซ เชเช เชธเซเชเชจเซเชกเชฎเชพเช) เช เชตเชฐเซเชงเชฟเชค เชฅเช เชเชพเชฏ เชเซ: เชฌเชงเชพ เชซเชฟเชฒเชธเซเชซเซ เชคเซเชฎเชจเซ เชกเชพเชฌเซ เชเชพเชเชเซ เชฒเซ เชเซ, เชชเชฐเชเชคเซ เชเชฎเชฃเซ เชเชพเชเชเซ เชจเชนเซเช. เชซเซเชฐเซเชเซเชธ เชเชฐเซ เชชเชเซ เชฎเซเชฒเซเชฏเซ เชงเชฐเชพเชตเซ เชเซ: 1 2 3 4 5.
เชเชเซเชคเชฟเชฎเชพเช, เชฅเซเชฐเซเชกเซเชจเซ เช เชตเชฐเซเชงเชฟเชค เชเชฐเชตเซเช (เชกเซเชกเชฒเซเช). เชฒเซเชฒเซ - เช เชฎเชฒ, เชฒเชพเชฒ - เชธเชฟเชเชเซเชฐเชจเชพเชเชเซเชถเชจ, เชเซเชฐเซ - เชฅเซเชฐเซเชก เชธเซเช เชฐเชนเซเชฏเซ เชเซ. เชฐเซเชฎเซเชฌเชธ เชเชพเชฐเซเชฏเซเชจเซ เชชเซเชฐเชพเชฐเชเชญ เชธเชฎเชฏ เชธเซเชเชตเซ เชเซ.
เชซเชฟเชฒเซเชธเซเชซเชฐเซเชธเชจเซ เชญเซเช
เชเซ เชเซ เชเชพเชธ เชเชฐเซเชจเซ เชตเชงเซ เชเซเชฐเชพเช เชตเชฟเชถเซ เชตเชฟเชเชพเชฐเชตเซเช เชเชฐเซเชฐเซ เชจเชฅเซ, เชชเชฐเชเชคเซ เชญเซเช เชเซเชเชจเซ เชชเชฃ เชซเชฟเชฒเชธเซเชซเซ เชเซเชกเซ เชฆเซ เชเซ. เชเชพเชฒเซ เชเชชเชฃเซ เชธเชฎเชธเซเชฏเชพเชฎเชพเช เชฅเซเชฐเซเชกเซเชจเซ เชญเซเชเชฎเชฐเชพเชจเซ เชชเชฐเชฟเชธเซเชฅเชฟเชคเชฟเชจเซเช เช เชจเซเชเชฐเชฃ เชเชฐเชตเชพเชจเซ เชชเซเชฐเชฏเชพเชธ เชเชฐเซเช. เชญเซเชเชฎเชฐเซ เช เชเซ เชเซเชฏเชพเชฐเซ เชฅเซเชฐเซเชก เชเชพเชฒเซ เชฐเชนเซเชฏเซ เชเซ, เชชเชฐเชเชคเซ เชจเซเชเชงเชชเชพเชคเซเชฐ เชเชพเชฎ เชเชฐเซเชฏเชพ เชตเชฟเชจเชพ, เชฌเซเชเชพ เชถเชฌเซเชฆเซเชฎเชพเช เชเชนเซเช เชคเซ, เช เชธเชฎเชพเชจ เชฎเชกเชพเชเชพเชเช เชเซ, เชซเชเซเชค เชนเชตเซ เชฅเซเชฐเซเชก เชธเซเชคเซ เชจเชฅเซ, เชชเชฐเชเชคเซ เชธเชเซเชฐเชฟเชฏเชชเชฃเซ เชเชพเชตเชพ เชฎเชพเชเซ เชเชเชเช เชถเซเชงเซ เชฐเชนเซเชฏเซ เชเซ, เชชเชฐเชเชคเซ เชคเซเชฏเชพเช เชเซเช เชเซเชฐเชพเช เชจเชฅเซ. เชตเชพเชฐเชเชตเชพเชฐ เช เชตเชฐเซเชงเชฟเชค เชฅเชตเชพเชฅเซ เชฌเชเชตเชพ เชฎเชพเชเซ, เชเซ เช เชฎเซ เชฌเซเชเซ เชเช เชจ เชฒเช เชถเชเซเช เชคเซ เช เชฎเซ เชเชพเชเชเซ เชชเชพเชเซ เชฎเซเชเซเชถเซเช.
// ะขะพ ะถะต ััะพ ะธ ะฒ 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
(เชเซ เชคเซเชฏเชพเช เชตเชชเชฐเชพเชฏ เชเซ). เชนเชตเซ เชคเซ เชเชพเชฃเซ เชเซ เชเซ เชฐเชพเชน เชเซเชจเชพเชฐเชพเชเชจเซ เชเชฃเชคเชฐเซ เชเซเชตเซ เชฐเซเชคเซ เชเชฐเชตเซ, เชคเซเชฎเชจเซ เชฅเซเชกเซ เชธเซเช เชเชตเซเช เช
เชจเซ เชตเชงเซ. เชตเชเซเชฐเซ. เชธเชพเชฎเชพเชจเซเชฏ เชฐเซเชคเซ, เชเชชเซเชเชฟเชฎเชพเชเช เชเชฐเชตเชพ เชฎเชพเชเซ เชถเชเซเชฏ เชฌเชงเซเช เชเชฐเซ เชเซ. เชชเชฐเชเชคเซ เชเชชเชฃเซ เชฏเชพเชฆ เชฐเชพเชเชตเซเช เชเซเชเช เชเซ เช เชนเชเซ เชชเชฃ เช เช เชธเชเซเชฐเชฟเชฏ เชเชเซเชฐ เชเซ เชเซ เชชเซเชฐเซเชธเซเชธเชฐ เชธเชเชธเชพเชงเชจเซเชจเซ เชเชพเช เชเชพเชฏ เชเซ เช
เชจเซ เชชเซเชฐเชตเชพเชนเชจเซ เชเชพเชณเชตเซ เชฐเชพเชเซ เชเซ, เชเซ เชญเซเชเชฎเชฐเซ เชคเชฐเชซ เชฆเซเชฐเซ เชถเชเซ เชเซ เชเซ เชเซเช เชซเชฟเชฒเชธเซเชซ เช
เชจเซเชฏ เชเชฐเชคเชพ เชตเชงเซ เช
เชเซเชฐเชคเชพ เชฌเชจเซ เชเชพเชฏ, เชชเชฐเชเชคเซ เชคเซเชจเซ เชชเชพเชธเซ เชธเซเชจเซเชฐเซ เชเชพเชเชเซ เชจเชฅเซ (เชชเซเชฐเชพเชฏเซเชฐเชฟเชเซ เชเชจเซเชตเชฐเซเชเชจ เชธเชฎเชธเซเชฏเชพ) . เชคเซเชฅเซ, เช
เชฎเซ เชคเซเชจเซ เชเชชเชฏเซเช เชซเชเซเชค เชตเชนเซเชเชเชพเชฏเซเชฒ เชฎเซเชฎเชฐเซเชฎเชพเช เชเซเชฌ เช เชเซเชเชเชพ เชซเซเชฐเชซเชพเชฐเซ เชฎเชพเชเซ เชเชฐเซเช เชเซเช, เชเซเชเชชเชฃ เชคเซเชคเซเชฏ-เชชเชเซเชท เชเซเชฒเซเชธ, เชจเซเชธเซเชเซเชก เชฒเซเชเซเชธ เช
เชจเซ เช
เชจเซเชฏ เชเชถเซเชเชฐเซเชฏ เชตเชฟเชจเชพ.
เชฎเชพเชเซ เชเชฟเชคเซเชฐเชเชพเชฎ SpinLock
. เชธเซเชเซเชฐเซเชฎเซเชธ เชธเซเชจเซเชฐเซ เชเชพเชเชเซ เชฎเชพเชเซ เชธเชคเชค "เชฒเชกเชพเช" เชเซ. เชจเชฟเชทเซเชซเชณเชคเชพเช เชเซ - เชเชเซเชคเชฟเชฎเชพเช, เชชเชธเชเชฆ เชเชฐเซเชฒ เชตเชฟเชธเซเชคเชพเชฐ. เชเซเชฐเซเชจเซ เชธเชเชชเซเชฐเซเชฃ เชเชชเชฏเซเช เชฅเชคเซ เชจเชฅเซ: เช เชเชพเชฐ เชฅเซเชฐเซเชกเซ เชฆเซเชตเชพเชฐเชพ เชฎเชพเชคเซเชฐ 2/3.
เช
เชนเซเช เช
เชจเซเชฏ เชเชเซเชฒ เชฎเชพเชคเซเชฐ เชเชชเชฏเซเช เชเชฐเชตเชพ เชฎเชพเชเซ เชนเชถเซ Interlocked.CompareExchange
เชเชชเชฐเชจเชพ เชเซเชกเชฎเชพเช (เชญเซเชเซเชฏเชพ เชคเชคเซเชตเชเซเชเชพเชจเซเชเชฎเชพเช) เชฌเชคเชพเชตเซเชฏเชพ เชชเซเชฐเชฎเชพเชฃเซ เชธเชฎเชพเชจ เชธเชเซเชฐเชฟเชฏ เชชเซเชฐเชคเซเชเซเชทเชพ เชธเชพเชฅเซ, เชชเชฐเชเชคเซ เช, เชชเชนเซเชฒเซเชฅเซ เช เชเชนเซเชฏเซเช เชคเซเชฎ, เชธเซเชฆเซเชงเชพเชเชคเชฟเช เชฐเซเชคเซ เช
เชตเชฐเซเชงเชฟเชค เชฅเช เชถเชเซ เชเซ.
เชชเชฐ Interlocked
เช เชจเซเชเชงเชตเซเช เชเซเชเช เชเซ เชคเซเชฏเชพเช เชฎเชพเชคเซเชฐ เชจเชฅเซ CompareExchange
, เชชเชฃ เช
เชฃเซ เชตเชพเชเชเชตเชพ เช
เชจเซ เชฒเชเชตเชพ เชฎเชพเชเซเชจเซ เช
เชจเซเชฏ เชชเชฆเซเชงเชคเชฟเช. เช
เชจเซ เชฌเชฆเชฒเชพเชตเชจเชพ เชชเซเชจเชฐเชพเชตเชฐเซเชคเชจ เชฆเซเชตเชพเชฐเชพ, เชเซ เชฌเซเชเชพ เชฅเซเชฐเซเชกเชฎเชพเช เชคเซเชจเชพ เชซเซเชฐเชซเชพเชฐเซ เชเชฐเชตเชพ เชฎเชพเชเซ เชธเชฎเชฏ เชนเซเชฏ (เชตเชพเชเชเซ 1, เชตเชพเชเชเซ 2, เชฒเชเซ 2, เชฒเชเซ 1 เชเชฐเชพเชฌ เชเซ), เชคเซเชจเซ เชเชชเชฏเซเช เชเช เชฎเซเชฒเซเชฏเชฎเชพเช เชเชเชฟเชฒ เชซเซเชฐเชซเชพเชฐเซ เชฎเชพเชเซ เชฅเช เชถเชเซ เชเซ (เชเชจเซเชเชฐเชฒเซเชเซเชก เชเชจเชฟเชฅเชฟเชเช เชชเซเชเชฐเซเชจ).
เชเชฐเซเชจเชฒ เชฎเซเชก เชธเซเชฒเซเชฏเซเชถเชจเซเชธ
เชฒเซเชชเชฎเชพเช เชธเชเชธเชพเชงเชจเซเชจเซ เชฌเชเชพเชก เชเชพเชณเชตเชพ เชฎเชพเชเซ, เชเชพเชฒเซ เชเซเชเช เชเซ เชเชชเชฃเซ เชฅเซเชฐเซเชกเชจเซ เชเซเชตเซ เชฐเซเชคเซ เช
เชตเชฐเซเชงเชฟเชค เชเชฐเซ เชถเชเซเช. เชฌเซเชเชพ เชถเชฌเซเชฆเซเชฎเชพเช เชเชนเซเช เชคเซ, เช
เชฎเชพเชฐเซเช เชเชฆเชพเชนเชฐเชฃ เชเชพเชฒเซ เชฐเชพเชเซเชจเซ, เชเชพเชฒเซ เชเซเชเช เชเซ เชตเซเชเชเชฐ เชเซเชตเซ เชฐเซเชคเซ เชซเชฟเชฒเซเชธเซเชซเชฐเชจเซ เชธเซเช เชเชพเชฏ เชเซ เช
เชจเซ เชเซเชฏเชพเชฐเซ เชเชฐเซเชฐเซ เชนเซเชฏ เชคเซเชฏเชพเชฐเซ เช เชคเซเชจเซ เชเชเชพเชกเซ เชเซ. เชชเซเชฐเชฅเชฎ, เชเชพเชฒเซ เชเซเชเช เชเซ เชเชชเชฐเซเชเชฟเชเช เชธเชฟเชธเซเชเชฎเชจเชพ เชเชฐเซเชจเชฒ เชฎเซเชก เชฆเซเชตเชพเชฐเชพ เช เชเซเชตเซ เชฐเซเชคเซ เชเชฐเชตเซเช. เชคเซเชฏเชพเชเชจเซ เชคเชฎเชพเชฎ เชฐเชเชจเชพเช เชเชฃเซ เชตเชเชค เชฏเซเชเชฐ เชธเซเชชเซเชธ เชเชฐเชคเชพเช เชงเซเชฎเซ เชนเซเชฏ เชเซ. เชเชฆเชพเชนเชฐเชฃ เชคเชฐเซเชเซ, เชเชฃเซ เชตเชเชค เชงเซเชฎเซเช AutoResetEvent
เชเชฆเชพเช 53 เชเชฃเซ เชงเซเชฎเซ SpinLock
[เชฐเชฟเชเซเชเชฐ]. เชชเชฐเชเชคเซ เชคเซเชฎเชจเซ เชธเชนเชพเชฏเชฅเซ, เชคเชฎเซ เชธเชฎเชเซเชฐ เชธเชฟเชธเซเชเชฎเชฎเชพเช เชชเซเชฐเชเซเชฐเชฟเชฏเชพเชเชจเซ เชธเซเชฎเซเชณ เชเชฐเซ เชถเชเซ เชเซ, เชตเซเชฏเชตเชธเซเชฅเชพเชชเชฟเชค เชเซ เชเซ เชจเชนเซเช.
เช
เชนเซเชเชจเซเช เชฎเซเชณ เชฌเชพเชเชงเชเชพเชฎ เช
เชกเชงเซ เชธเชฆเซ เชชเชนเซเชฒเชพเช เชกเชฟเชเชเซเชธเซเชเซเชฐเชพ เชฆเซเชตเชพเชฐเชพ เชชเซเชฐเชธเซเชคเชพเชตเชฟเชค เชธเซเชฎเชพเชซเซเชฐ เชเซ. เชธเซเชฎเชพเชซเซเชฐ, เชธเชฐเชณ เชถเชฌเซเชฆเซเชฎเชพเช เชเชนเซเช เชคเซ, เชธเชฟเชธเซเชเชฎ เชฆเซเชตเชพเชฐเชพ เชธเชเชเชพเชฒเชฟเชค เชเช เชธเชเชพเชฐเชพเชคเซเชฎเช เชชเซเชฐเซเชฃเชพเชเช เชเซ, เช
เชจเซ เชคเซเชจเชพ เชชเชฐ เชฌเซ เชเชพเชฎเชเซเชฐเซ, เชตเชงเชพเชฐเซ เช
เชจเซ เชเชเชพเชกเซ. เชเซ เชคเซ เชเชเชพเชกเชตเชพเชฎเชพเช เชจเชฟเชทเซเชซเชณ เชเชพเชฏ, เชถเซเชจเซเชฏ, เชคเซ เชเซเชฒเชฟเชเช เชฅเซเชฐเซเชก เช
เชตเชฐเซเชงเชฟเชค เชเซ. เชเซเชฏเชพเชฐเซ เชเซเช เช
เชจเซเชฏ เชธเชเซเชฐเชฟเชฏ เชฅเซเชฐเซเชก/เชชเซเชฐเชเซเชฐเชฟเชฏเชพ เชฆเซเชตเชพเชฐเชพ เชธเชเชเซเชฏเชพ เชตเชงเชพเชฐเชตเชพเชฎเชพเช เชเชตเซ เชเซ, เชคเซเชฏเชพเชฐเซ เชฅเซเชฐเซเชกเซ เชเซเชกเชตเชพเชฎเชพเช เชเชตเซ เชเซ เช
เชจเซ เชชเชพเชธ เชเชฐเซเชฒ เชธเชเชเซเชฏเชพ เชฆเซเชตเชพเชฐเชพ เชธเซเชฎเชพเชซเซเชฐ เชซเชฐเซเชฅเซ เชเชเซ เชเซ. เชเซเช เชธเซเชฎเชพเชซเซเชฐ เชธเชพเชฅเซ เช
เชกเชเชฃเชฎเชพเช เชฐเชนเซเชฒเซ เชเซเชฐเซเชจเซเชจเซ เชเชฒเซเชชเชจเชพ เชเชฐเซ เชถเชเซ เชเซ. .NET เชธเชฎเชพเชจ เชเชพเชฐเซเชฏเชเซเชทเชฎเชคเชพ เชธเชพเชฅเซ เช
เชจเซเช เชฐเชเชจเชพเช เชเชซเชฐ เชเชฐเซ เชเซ: AutoResetEvent
, ManualResetEvent
, Mutex
เช
เชจเซ เชฎเชพเชฐเซ เชเชพเชคเชจเซ Semaphore
. เช
เชฎเซ เชเชชเชฏเซเช เชเชฐเซเชถเซเช AutoResetEvent
, เช เชฌเชพเชเชงเชเชพเชฎเซเชฎเชพเช เช เชธเซเชฅเซ เชธเชฐเชณ เชเซ: เชซเชเซเชค เชฌเซ เชฎเซเชฒเซเชฏเซ 0 เช
เชจเซ 1 (เชเซเชเซเช, เชธเชพเชเซเช). เชคเซเชฃเซเชจเซ เชชเชฆเซเชงเชคเชฟ WaitOne()
เชเซ เชฎเซเชฒเซเชฏ 0 เชนเซเชฏ เชคเซ เชเซเชฒเชฟเชเช เชฅเซเชฐเซเชกเชจเซ เช
เชตเชฐเซเชงเชฟเชค เชเชฐเซ เชเซ, เช
เชจเซ เชเซ 1, เชคเซ เชคเซเชจเซ 0 เชธเซเชงเซ เชเชเชพเชกเซ เชเซ เช
เชจเซ เชคเซเชจเซ เชเซเชกเซ เชฆเซ เชเซ. เชเช เชชเชฆเซเชงเชคเชฟ Set()
1 เชธเซเชงเซ เชตเชงเซ เชเซ เช
เชจเซ เชเช เชตเซเชเชเชฐเชจเซ เชชเชธเชพเชฐ เชฅเชตเชพ เชฆเซ เชเซ, เชเซ เชซเชฐเซเชฅเซ 0 เชธเซเชงเซ เชเชเชพเชกเซ เชเซ. เชธเชฌเชตเซ เชเชฐเซเชจเชธเซเชเชพเชเชฒเชจเซ เชเซเชฎ เชเชพเชฐเซเชฏ เชเชฐเซ เชเซ.
เชเชพเชฒเซ เชเชเซเชฒเชจเซ เชเชเชฟเชฒ เชฌเชจเชพเชตเซเช เช เชจเซ เชฆเชฐเซเช เชซเชฟเชฒเซเชธเซเชซเชฐ เชฎเชพเชเซ เชฒเซเชเชจเซ เชเชชเชฏเซเช เชเชฐเซเช, เช เชจเซ เชเช เช เชธเชฎเชฏเซ เชฌเชงเชพ เชฎเชพเชเซ เชจเชนเซเช. เชคเซ. เชนเชตเซ เชเช เชธเชพเชฅเซ เช เชจเซเช เชซเชฟเชฒเชธเซเชซเซ เชนเซเช เชถเชเซ เชเซ, เชเช เชจเชนเซเช. เชชเชฐเชเชคเซ เช เชฎเซ เชซเชฐเซเชฅเซ เชเซเชฌเชฒเชจเซ เชเชเซเชธเซเชธเชจเซ เชฏเซเชเซเชฏ เชฐเซเชคเซ เช เชตเชฐเซเชงเชฟเชค เชเชฐเซเช เชเซเช, เชฐเซเชธ (เชเชพเชคเชฟเชจเซ เชธเซเชฅเชฟเชคเชฟ) เชเชพเชณเชตเชพ, เชเชพเชคเชฐเซเชชเซเชฐเซเชตเช เชฌเซเชเซเชธ เชฒเซเชตเชพ.
// ะะปั ะฑะปะพะบะธัะพะฒะฐะฝะธั ะพัะดะตะปัะฝะพะณะพ ัะธะปะพัะพัะฐ.
// ะะฝะธัะธะฐะปะธะทะธััะตััั: new AutoResetEvent(true) ะดะปั ะบะฐะถะดะพะณะพ.
private AutoResetEvent[] philosopherEvents;
// ะะปั ะดะพัััะฟะฐ ะบ ะฒะธะปะบะฐะผ / ะดะพัััะฟ ะบ ััะพะปั.
private AutoResetEvent tableEvent = new AutoResetEvent(true);
// ะ ะพะถะดะตะฝะธะต ัะธะปะพัะพัะฐ.
public void Run(int i, CancellationToken token)
{
while (true)
{
TakeForks(i); // ะะดะตั ะฒะธะปะบะธ.
// ะะฑะตะด. ะะพะถะตั ะฑััั ะธ ะดะพะปััะต.
eatenFood[i] = (eatenFood[i] + 1) % (int.MaxValue - 1);
PutForks(i); // ะัะดะฐัั ะฒะธะปะบะธ ะธ ัะฐะทะฑะปะพะบะธัะพะฒะฐัั ัะพัะตะดะตะน.
Think(i);
if (token.IsCancellationRequested) break;
}
}
// ะะถะธะดะฐัั ะฒะธะปะบะธ ะฒ ะฑะปะพะบะธัะพะฒะบะต.
void TakeForks(int i)
{
bool hasForks = false;
while (!hasForks) // ะะพะฟัะพะฑะพะฒะฐัั ะตัะต ัะฐะท (ะฑะปะพะบะธัะพะฒะบะฐ ะฝะต ะทะดะตัั).
{
// ะัะบะปััะฐััะธะน ะดะพัััะฟ ะบ ััะพะปั, ะฑะตะท ะณะพะฝะพะบ ะทะฐ ะฒะธะปะบะฐะผะธ.
tableEvent.WaitOne();
if (forks[Left(i)] == 0 && forks[Right(i)] == 0)
forks[Left(i)] = forks[Right(i)] = i + 1;
hasForks = forks[Left(i)] == i + 1 && forks[Right(i)] == i + 1;
if (hasForks)
// ะขะตะฟะตัั ัะธะปะพัะพั ะฟะพะตัั, ะฒัะนะดะตั ะธะท ัะธะบะปะฐ. ะัะปะธ Set
// ะฒัะทะฒะฐะฝ ะดะฒะฐะถะดั, ัะพ ะทะฝะฐัะตะฝะธะต true.
philosopherEvents[i].Set();
// ะ ะฐะทะฑะปะพะบะธัะพะฒะฐัั ะพะดะฝะพะณะพ ะพะถะธะดะฐััะตะณะพ. ะะพัะปะต ะฝะตะณะพ ะทะฝะฐัะตะฝะธะต tableEvent ะฒ false.
tableEvent.Set();
// ะัะปะธ ะธะผะตะตั true, ะฝะต ะฑะปะพะบะธััะตััั, ะฐ ะตัะปะธ false, ัะพ ะฑัะดะตั ะถะดะฐัั Set ะพั ัะพัะตะดะฐ.
philosopherEvents[i].WaitOne();
}
}
// ะัะดะฐัั ะฒะธะปะบะธ ะธ ัะฐะทะฑะปะพะบะธัะพะฒะฐัั ัะพัะตะดะตะน.
void PutForks(int i)
{
tableEvent.WaitOne(); // ะะตะท ะณะพะฝะพะบ ะทะฐ ะฒะธะปะบะฐะผะธ.
forks[Left(i)] = 0;
// ะัะพะฑัะดะธัั ะปะตะฒะพะณะพ, ะฐ ะฟะพัะพะผ ะธ ะฟัะฐะฒะพะณะพ ัะพัะตะดะฐ, ะปะธะฑะพ AutoResetEvent ะฒ true.
philosopherEvents[LeftPhilosopher(i)].Set();
forks[Right(i)] = 0;
philosopherEvents[RightPhilosopher(i)].Set();
tableEvent.Set();
}
เช
เชนเซเช เชถเซเช เชฅเช เชฐเชนเซเชฏเซเช เชเซ เชคเซ เชธเชฎเชเชตเชพ เชฎเชพเชเซ, เชเซเชฏเชพเชฐเซ เชซเชฟเชฒเชธเซเชซ เชซเซเชฐเซเชเชธ เชฒเซเชตเชพเชฎเชพเช เชจเชฟเชทเซเชซเชณ เชเชฏเซ เชคเซเชฏเชพเชฐเซ เชเซเชธเชจเซ เชงเซเชฏเชพเชจเชฎเชพเช เชฒเซ, เชชเชเซ เชคเซเชจเซ เชเซเชฐเชฟเชฏเชพเช เชจเซเชเซ เชฎเซเชเชฌ เชนเชถเซ. เชคเซ เชเซเชฌเชฒ เชชเชฐ เชชเชนเซเชเชเชตเชพเชจเซ เชฐเชพเชน เชเซเช เชฐเชนเซเชฏเซ เชเซ. เชคเซ เชชเซเชฐเชพเชชเซเชค เชเชฐเซเชฏเชพ เชชเชเซ, เชคเซ เชเชพเชเชเซ เชฒเซเชตเชพเชจเซ เชชเซเชฐเชฏเชพเชธ เชเชฐเซ เชเซ. เชเชพเชฎ เชเชฐเซเชฏเซเช เชจเชฅเซ. เชคเซ เชเซเชฌเชฒเชจเซ เชเชเซเชธเซเชธ เชเชชเซ เชเซ (เชชเชฐเชธเซเชชเชฐ เชฌเชพเชเชพเชค). เช
เชจเซ เชคเซเชจเซ "เชเชฐเซเชจเชธเซเชเชพเชเชฒ" เชชเชธเชพเชฐ เชเชฐเซ เชเซ (AutoResetEvent
) (เชคเซเช เชถเชฐเซเชเชคเชฎเชพเช เชเซเชฒเซเชฒเชพ เชเซ). เชคเซ เชซเชฐเซเชฅเซ เชเชเซเชฐเชฎเชพเช เชเชตเซ เชเซ, เชเชพเชฐเชฃ เชเซ เชคเซเชจเซ เชชเชพเชธเซ เชเชพเชเชเซ เชจเชฅเซ. เชคเซ เชคเซเชฎเชจเซ เชฒเซเชตเชพเชจเซ เชชเซเชฐเชฏเชพเชธ เชเชฐเซ เชเซ เช
เชจเซ เชคเซเชจเชพ "เชเชฐเซเชจเชธเซเชเชพเชเชฒ" เชชเชฐ เช
เชเชเซ เชเชพเชฏ เชเซ. เชเชฎเชฃเซ เชเซ เชกเชพเชฌเซ เชฌเชพเชเซเชจเชพ เชเซเชเชฒเชพเช เชตเชงเซ เชจเชธเซเชฌเชฆเชพเชฐ เชชเชพเชกเซเชถเซ, เชเชพเชตเซเช เชธเชฎเชพเชชเซเชค เชเชฐเซเชฏเชพ เชชเชเซ, เช
เชฎเชพเชฐเชพ เชซเชฟเชฒเซเชธเซเชซเชฐเชจเซ "เชคเซเชฎเชจเซ เชเชฐเซเชจเชธเซเชเชพเชเชฒ เชเซเชฒเซเชจเซ" เชเซเชฒเซ เชเซ. เชเชชเชฃเชพ เชซเชฟเชฒเซเชธเซเชซเชฐ เชฌเซเชเซ เชตเชพเชฐ เชคเซเชจเซ เชชเชธเชพเชฐ เชเชฐเซ เชเซ (เช
เชจเซ เชคเซ เชคเซเชจเซ เชชเชพเชเชณ เชฌเชเชง เชฅเชพเชฏ เชเซ). เชคเซ เชคเซเชฐเซเชเซ เชตเชเชค เชเชพเชเชเซ เชฒเซเชตเชพเชจเซ เชชเซเชฐเชฏเชคเซเชจ เชเชฐเซ เชเซ. เชธเชพเชฐเชพ เชจเชธเซเชฌ. เช
เชจเซ เชคเซ เชเชฎเชตเชพ เชฎเชพเชเซ เชคเซเชจเซ เชเชฐเซเชจเชธเซเชเชพเชเชฒ เชชเชธเชพเชฐ เชเชฐเซ เชเซ.
เชเซเชฏเชพเชฐเซ เชเชตเชพ เชเซเชกเชฎเชพเช เชฐเซเชจเซเชกเชฎ เชญเซเชฒเซ เชนเซเชฏ เชเซ (เชคเซ เชนเชเชฎเซเชถเชพ เช
เชธเซเชคเชฟเชคเซเชตเชฎเชพเช เชนเซเชฏ เชเซ), เชเชฆเชพเชนเชฐเชฃ เชคเชฐเซเชเซ, เชชเชพเชกเซเชถเซเชจเซ เชเซเชเซ เชฐเซเชคเซ เชเชฒเซเชฒเซเชเชฟเชค เชเชฐเชตเชพเชฎเชพเช เชเชตเซ เชเซ เช
เชฅเชตเชพ เชคเซ เช เชเชฌเซเชเซเชเซเช เชฌเชจเชพเชตเชตเชพเชฎเชพเช เชเชตเซ เชเซ AutoResetEvent
เชฌเชงเชพ เชฎเชพเชเซ (Enumerable.Repeat
), เชชเชเซ เชซเชฟเชฒเซเชธเซเชซเชฐเซ เชตเชฟเชเชพเชธเชเชฐเซเชคเชพเชเชจเซ เชฐเชพเชน เชเซเชถเซ, เชเชพเชฐเชฃ เชเซ เชเชตเชพ เชเซเชกเชฎเชพเช เชญเซเชฒเซ เชถเซเชงเชตเซ เช เชเซเชฌ เชฎเซเชถเซเชเซเชฒ เชเชพเชฐเซเชฏ เชเซ. เช เชเชเซเชฒ เชธเชพเชฅเซเชจเซ เชฌเซเชเซ เชธเชฎเชธเซเชฏเชพ เช เชเซ เชเซ เชคเซ เชเชพเชคเชฐเซ เชเชชเชคเซเช เชจเชฅเซ เชเซ เชเซเช เชซเชฟเชฒเชธเซเชซ เชญเซเชเซ เชฎเชฐเชถเซ เชจเชนเซเช.
เชนเชพเชเชฌเซเชฐเชฟเชก เชธเซเชฒเซเชฏเซเชถเชจเซเชธ
เช
เชฎเซ เชธเชฎเชฏ เชฎเชพเชเซเชจเชพ เชฌเซ เช
เชญเชฟเชเชฎเซ เชเซเชฏเชพ เชเซ, เชเซเชฏเชพเชฐเซ เช
เชฎเซ เชตเชชเชฐเชพเชถเชเชฐเซเชคเชพ เชฎเซเชก เช
เชจเซ เชฒเซเชชเชฎเชพเช เชฐเชนเซเช เชเซเช, เช
เชจเซ เชเซเชฏเชพเชฐเซ เช
เชฎเซ เชเชฐเซเชจเชฒ เชฆเซเชตเชพเชฐเชพ เชฅเซเชฐเซเชกเชจเซ เช
เชตเชฐเซเชงเชฟเชค เชเชฐเซเช เชเซเช. เชชเซเชฐเชฅเชฎ เชชเชฆเซเชงเชคเชฟ เชเซเชเชเชพ เชคเชพเชณเชพเช เชฎเชพเชเซ เชธเชพเชฐเซ เชเซ, เชฌเซเชเซ เชฒเชพเชเชฌเซ เชฐเชพเชถเชฟเช เชฎเชพเชเซ. เชฒเซเชชเชฎเชพเช เชฌเชฆเชฒเชพเชต เชฎเชพเชเซ เชตเซเชฐเซเชเชฌเชฒเชจเซ เชชเซเชฐเชฅเชฎ เชธเชเชเซเชทเชฟเชชเซเชคเชฎเชพเช เชฐเชพเชน เชเซเชตเซ เชเชฃเซเชตเชพเชฐ เชเชฐเซเชฐเซ เชเซ, เช
เชจเซ เชชเชเซ เชเซเชฏเชพเชฐเซ เชฐเชพเชน เชฒเชพเชเชฌเซ เชนเซเชฏ เชคเซเชฏเชพเชฐเซ เชฅเซเชฐเซเชกเชจเซ เช
เชตเชฐเซเชงเชฟเชค เชเชฐเซ. เช เช
เชญเชฟเชเชฎ เชเชนเซเชตเชพเชคเชพ เชฎเชพเช เชฒเชพเชเซ เชเชฐเชตเชพเชฎเชพเช เชเชตเซ เชเซ. เชตเชฐเซเชฃเชธเชเชเชฐ เชฐเชเชจเชพเช. เช
เชนเซเช เชเชฐเซเชจเชฒ เชฎเซเชก เชฎเชพเชเซ เชธเชฎเชพเชจ เชฐเชเชจเชพเช เชเซ, เชชเชฐเชเชคเซ เชนเชตเซ เชตเชชเชฐเชพเชถเชเชฐเซเชคเชพ เชฎเซเชก เชฒเซเชช เชธเชพเชฅเซ: SemaphorSlim
, ManualResetEventSlim
เชตเชเซเชฐเซ. เช
เชนเซเชเชจเซ เชธเซเชฅเซ เชฒเซเชเชชเซเชฐเชฟเชฏ เชกเชฟเชเชพเชเชจ เชเซ Monitor
, เชเชพเชฐเชฃ เชเซ C# เชฎเชพเช เชเช เชเชพเชฃเซเชคเซเช เชเซ lock
เชตเชพเชเซเชฏเชฐเชเชจเชพ Monitor
เช เช เช เชธเซเชฎเชพเชซเซเชฐ เชเซ เชเซเชจเซ เชฎเชนเชคเซเชคเชฎ เชเชฟเชเชฎเชค 1 (เชฎเซเชฏเซเชเซเชเซเชธ) เชเซ, เชชเชฐเชเชคเซ เชฒเซเชช, เชฐเชฟเชเชฐเซเชเชจ, เชเชจเซเชกเชฟเชถเชจ เชตเซเชฐเซเชเชฌเชฒ เชชเซเชเชฐเซเชจ (เชจเซเชเซ เชคเซเชจเชพ เชชเชฐ เชตเชงเซ), เชตเชเซเชฐเซเชฎเชพเช เชฐเชพเชน เชเซเชตเชพ เชฎเชพเชเซ เชธเชชเซเชฐเซเช เชธเชพเชฅเซ. เชเชพเชฒเซ เชคเซเชจเซ เชธเชพเชฅเซ เชเชเซเชฒ เชเซเชเช.
// ะกะฟัััะตะผ ะพะฑัะตะบั ะดะปั ะะพะฝะธัะพัะฐ ะพั ะฒัะตั
, ััะพะฑั ะฑะตะท ะดะตะดะปะพะบะพะฒ.
private readonly object _lock = new object();
// ะัะตะผั ะพะถะธะดะฐะฝะธั ะฟะพัะพะบะฐ.
private DateTime?[] _waitTimes = new DateTime?[philosophersAmount];
public void Run(int i, CancellationToken token)
{
while (true)
{
TakeForks(i);
eatenFood[i] = (eatenFood[i] + 1) % (int.MaxValue - 1);
PutForks(i);
Think(i);
if (token.IsCancellationRequested) break;
}
}
// ะะฐัะต ัะปะพะถะฝะพะต ััะปะพะฒะธะต ะดะปั Condition Variable ะฟะฐััะตัะฝะฐ.
bool CanIEat(int i)
{
// ะัะปะธ ะตััั ะฒะธะปะบะธ:
if (forks[Left(i)] != 0 && forks[Right(i)] != 0)
return false;
var now = DateTime.Now;
// ะะพะถะตั, ะตัะปะธ ัะพัะตะดะธ ะฝะต ะฑะพะปะตะต ะณะพะปะพะดะฝัะต, ัะตะผ ัะตะบััะธะน.
foreach(var p in new int[] {LeftPhilosopher(i), RightPhilosopher(i)})
if (_waitTimes[p] != null && now - _waitTimes[p] > now - _waitTimes[i])
return false;
return true;
}
void TakeForks(int i)
{
// ะะฐะนัะธ ะฒ ะะพะฝะธัะพั. ะขะพ ะถะต ัะฐะผะพะต: lock(_lock) {..}.
// ะัะทัะฒะฐะตะผ ะฒะฝะต try, ััะพะฑั ะฒะพะทะผะพะถะฝะพะต ะธัะบะปััะตะฝะธะต ะฒัะฑัะฐััะฒะฐะปะพัั ะฒััะต.
bool lockTaken = false;
Monitor.Enter(_lock, ref lockTaken);
try
{
_waitTimes[i] = DateTime.Now;
// Condition Variable ะฟะฐััะตัะฝ. ะัะฒะพะฑะพะถะดะฐะตะผ ะปะพะบ, ะตัะปะธ ะฝะต ะฒัะฟะพะปะฝะตะฝะฝะพ
// ัะปะพะถะฝะพะต ััะปะพะฒะธะต. ะ ะถะดะตะผ ะฟะพะบะฐ ะบัะพ-ะฝะธะฑัะดั ัะดะตะปะฐะตั Pulse / PulseAll.
while (!CanIEat(i))
Monitor.Wait(_lock);
forks[Left(i)] = i + 1;
forks[Right(i)] = i + 1;
_waitTimes[i] = null;
}
finally
{
if (lockTaken) Monitor.Exit(_lock);
}
}
void PutForks(int i)
{
// ะขะพ ะถะต ัะฐะผะพะต: lock (_lock) {..}.
bool lockTaken = false;
Monitor.Enter(_lock, ref lockTaken);
try
{
forks[Left(i)] = 0;
forks[Right(i)] = 0;
// ะัะฒะพะฑะพะดะธัั ะฒัะต ะฟะพัะพะบะธ ะฒ ะพัะตัะตะดะธ ะะะกะะ ะฒัะทะพะฒะฐ Monitor.Exit.
Monitor.PulseAll(_lock);
}
finally
{
if (lockTaken) Monitor.Exit(_lock);
}
}
เช เชนเซเช เช เชฎเซ เชซเซเชฐเซเชเซเชธเชจเซ เชเชเซเชธเซเชธ เชฎเชพเชเซ เชเชเชพ เชเซเชฌเชฒเชจเซ เชซเชฐเซเชฅเซ เช เชตเชฐเซเชงเชฟเชค เชเชฐเซ เชฐเชนเซเชฏเชพ เชเซเช, เชชเชฐเชเชคเซ เชนเชตเซ เช เชฎเซ เชเช เช เชธเชฎเชฏเซ เชคเชฎเชพเชฎ เชฅเซเชฐเซเชกเซเชจเซ เช เชจเชพเชตเชฐเซเชงเชฟเชค เชเชฐเซ เชฐเชนเซเชฏเชพ เชเซเช, เช เชจเซ เชเซเชฏเชพเชฐเซ เชเซเช เชเชพเชตเซเช เชธเชฎเชพเชชเซเชค เชเชฐเซ เชคเซเชฏเชพเชฐเซ เชชเชกเซเชถเซเชเชจเซ เชจเชนเซเช. เชคเซ. เชชเซเชฐเชฅเชฎ, เชเซเช เชตเซเชฏเชเซเชคเชฟ เชชเชกเซเชถเซเชเชจเซ เชเชพเชฏ เชเซ เช เชจเซ เช เชตเชฐเซเชงเซ เชเซ, เช เชจเซ เชเซเชฏเชพเชฐเซ เชเซเช เช เชธเชฎเชพเชชเซเชค เชเชฐเซ เชเซ, เชชเชฐเชเชคเซ เชคเชฐเชค เช เชซเชฐเซเชฅเซ เชเชพเชตเชพ เชฎเชพเชเชเซ เชเซ, เชคเซเชฏเชพเชฐเซ เชคเซ เชฌเซเชฒเซเชเชฟเชเชเชฎเชพเช เชเชพเชฏ เชเซ เช เชจเซ เชคเซเชจเชพ เชชเชกเซเชถเซเชเชจเซ เชเชเชพเชกเซ เชเซ, เชเชพเชฐเชฃ เชเซ. เชคเซเชจเซ เชฐเชพเชน เชเซเชตเชพเชจเซ เชธเชฎเชฏ เชเชเซ เชเซ.
เช เชฐเซเชคเซ เชเชชเชฃเซ เชฎเชกเชพเชเชพเชเช เช
เชจเซ เชเซเชเชฒเชพเช เชซเชฟเชฒเชธเซเชซเชจเซ เชญเซเชเชฎเชฐเซ เชเชพเชณเซเช เชเซเช. เช
เชฎเซ เชเซเชเชเชพ เชฐเชพเชน เชฎเชพเชเซ เชฒเซเชชเชจเซ เชเชชเชฏเซเช เชเชฐเซเช เชเซเช เช
เชจเซ เชฒเชพเชเชฌเชพ เชธเชฎเชฏ เชฎเชพเชเซ เชฅเซเชฐเซเชกเชจเซ เช
เชตเชฐเซเชงเชฟเชค เชเชฐเซเช เชเซเช. เชฆเชฐเซเชเชจเซ เชเชเชธเชพเชฅเซ เช
เชจเชพเชตเชฐเซเชงเชฟเชค เชเชฐเชตเชพเชจเซเช เชงเซเชฎเชพ เชเซ เชเซ เชฎเชพเชคเซเชฐ เชชเชพเชกเซเชถเซเชจเซ เช
เชจเชพเชตเชฐเซเชงเชฟเชค เชเชฐเชตเชพเชฎเชพเช เชเชตเซเชฏเซเช เชนเซเชฏ, เชเซเชฎ เชเซ เชธเชพเชฅเซเชจเชพ เชเชเซเชฒเชฎเชพเช AutoResetEvent
, เชชเชฐเชเชคเซ เชคเชซเชพเชตเชค เชฎเซเชเซ เชจ เชนเซเชตเซ เชเซเชเช, เชเชพเชฐเชฃ เชเซ เชฅเซเชฐเซเชกเซ เชชเชนเซเชฒเชพ เชฏเซเชเชฐ เชฎเซเชกเชฎเชพเช เชฐเชนเซเชตเซเช เชเซเชเช.
ะฃ lock
เชธเชฟเชจเซเชเซเชเซเชธเชฎเชพเช เชฌเซเชญเชคเซเชธ เชเชถเซเชเชฐเซเชฏ เชเซ. เชเชชเชฏเซเช เชเชฐเชตเชพเชจเซ เชญเชฒเชพเชฎเชฃ เชเชฐเซ Monitor
เชธเซเชงเซเช [เชฐเชฟเชเซเชเชฐ] [เชเชฐเชฟเช เชฒเชฟเชชเชฐเซเช]. เชคเซเชฎเชพเชเชฅเซ เชเช เชเซ lock
เชนเชเชฎเซเชถเชพ เชฌเชนเชพเชฐ Monitor
, เชเซ เชคเซเชฏเชพเช เช
เชชเชตเชพเชฆ เชนเซเชฏ เชคเซ เชชเชฃ, เชเซ เชเชฟเชธเซเชธเชพเชฎเชพเช เช
เชจเซเชฏ เชฅเซเชฐเซเชก เชถเซเชฐ เชเชฐเซเชฒ เชฎเซเชฎเชฐเซ เชธเซเชฅเชฟเชคเชฟเชจเซ เชฌเชฆเชฒเซ เชถเชเซ เชเซ. เชเชตเชพ เชเชฟเชธเซเชธเชพเชเชฎเชพเช, เชกเซเชกเชฒเซเชเชฎเชพเช เชเชตเซเช เช
เชฅเชตเชพ เชเซเชเช เชฐเซเชคเซ เชชเซเชฐเซเชเซเชฐเชพเชฎเชจเซ เชธเซเชฐเชเซเชทเชฟเชค เชฐเซเชคเซ เชธเชฎเชพเชชเซเชค เชเชฐเชตเซเช เชตเชงเซ เชธเชพเชฐเซเช เชเซ. เชฌเซเชเซเช เชเชถเซเชเชฐเซเชฏ เช เชเซ เชเซ เชฎเซเชจเชฟเชเชฐ เชธเชฟเชเชเซเชฐเชจเชพเชเชเซเชถเชจ เชฌเซเชฒเซเชเชจเซ เชเชชเชฏเซเช เชเชฐเซ เชเซ (SyncBlock
), เชเซ เชคเชฎเชพเชฎ เชชเชฆเชพเชฐเซเชฅเซเชฎเชพเช เชนเชพเชเชฐ เชเซ. เชคเซเชฅเซ, เชเซ เชเซเช เช
เชฏเซเชเซเชฏ เชเชฌเซเชเซเชเซเช เชชเชธเชเชฆ เชเชฐเซเชฒ เชนเซเชฏ, เชคเซ เชคเชฎเซ เชธเชฐเชณเชคเชพเชฅเซ เชกเซเชกเชฒเซเช เชฎเซเชณเชตเซ เชถเชเซ เชเซ (เชเชฆเชพเชนเชฐเชฃ เชคเชฐเซเชเซ, เชเซ เชคเชฎเซ เชเชเชคเชฐเชฟเช เชธเซเชเซเชฐเชฟเชเช เชชเชฐ เชฒเซเช เชเชฐเซ เชเซ). เช
เชฎเซ เช เชฎเชพเชเซ เชนเชเชฎเซเชถเชพ เชเซเชชเชพเชฏเซเชฒเชพ เชชเชฆเชพเชฐเซเชฅเชจเซ เชเชชเชฏเซเช เชเชฐเซเช เชเซเช.
เชเชจเซเชกเชฟเชถเชจ เชตเซเชฐเชฟเชเชฌเชฒ เชชเซเชเชฐเซเชจ เชคเชฎเชจเซ เชเซเชเชฒเซเช เชเชเชฟเชฒ เชธเซเชฅเชฟเชคเชฟเชจเซ เช เชชเซเชเซเชทเชพเชจเซ เชตเชงเซ เชธเชเชเซเชทเชฟเชชเซเชคเชฎเชพเช เช เชฎเชฒเชฎเชพเช เชฎเซเชเชตเชพเชจเซ เชฎเชเชเซเชฐเซ เชเชชเซ เชเซ. .NET เชฎเชพเช, เชคเซ เช เชงเซเชฐเซเช เชเซ, เชฎเชพเชฐเชพ เชฎเชคเซ, เชเชพเชฐเชฃ เชเซ เชธเซเชฆเซเชงเชพเชเชคเชฟเช เชฐเซเชคเซ, เชเชฃเชพ เชตเซเชฐเชฟเชฏเซเชฌเชฒเซเชธ เชชเชฐ เชเชฃเซ เชเชคเชพเชฐ เชนเซเชตเซ เชเซเชเช (เชเซเชฎ เชเซ เชชเซเชธเชฟเชเซเชธ เชฅเซเชฐเซเชกเซเชฎเชพเช), เช เชจเซ เชเช เชฒเซเช เชชเชฐ เชจเชนเซเช. เชชเชเซ เชเซเช เชคเซเชฎเชจเซ เชฌเชงเชพ เชซเชฟเชฒเชธเซเชซเซ เชฎเชพเชเซ เชฌเชจเชพเชตเซ เชถเชเซ เชเซ. เชชเชฐเชเชคเซ เช เชซเซเชฐเซเชฎเชฎเชพเช เชชเชฃ, เชคเซ เชคเชฎเชจเซ เชเซเชก เชเชเชพเชกเชตเชพเชจเซ เชฎเชเชเซเชฐเซ เชเชชเซ เชเซ.
เชเชฃเชพ เชซเชฟเชฒเชธเซเชซเซ เช
เชฅเชตเชพ async
/ await
เช เซเช เชเซ, เชนเชตเซ เชเชชเชฃเซ เชฅเซเชฐเซเชกเซเชจเซ เช เชธเชฐเชเชพเชฐเช เชฐเซเชคเซ เชฌเซเชฒเซเช เชเชฐเซ เชถเชเซเช เชเซเช. เชชเชฐเชเชคเซ เชเซ เชเชชเชฃเซ เชชเชพเชธเซ เชเชฃเชพ เชซเชฟเชฒเซเชธเซเชซเชฐเซ เชนเซเชฏ เชคเซ? 100? 10000? เชเชฆเชพเชนเชฐเชฃ เชคเชฐเซเชเซ, เช เชฎเชจเซ เชตเซเชฌ เชธเชฐเซเชตเชฐ เชชเชฐ 100000 เชตเชฟเชจเชเชคเซเช เชฎเชณเซ เชเซ. เชฆเชฐเซเช เชตเชฟเชจเชเชคเซ เชฎเชพเชเซ เชฅเซเชฐเซเชก เชฌเชจเชพเชตเชตเชพ เชฎเชพเชเซ เชคเซ เชเชตเชฐเชนเซเชก เชนเชถเซ, เชเชพเชฐเชฃ เชเซ เชเชฃเชพ เชฅเซเชฐเซเชกเซ เชธเชฎเชพเชเชคเชฐ เชเชพเชฒเชถเซ เชจเชนเซเช. เชฒเซเชเชฟเชเชฒ เชเซเชฐเซ เชเซ เชคเซเชเชฒเชพ เช เชเชพเชฒเชถเซ (เชฎเชพเชฐเซ เชชเชพเชธเซ 4 เชเซ). เช เชจเซ เชฌเชพเชเซเชจเชพ เชฌเชงเชพ เช เชธเชเชธเชพเชงเชจเซ เชเซเชจเชตเซ เชฒเซเชถเซ. เช เชธเชฎเชธเซเชฏเชพเชจเซ เชเช เชเชเซเชฒ เช async / await เชชเซเชเชฐเซเชจ เชเซ. เชคเซเชจเซ เชตเชฟเชเชพเชฐ เช เชเซ เชเซ เชเชพเชฐเซเชฏ เชฅเซเชฐเซเชกเชจเซ เชชเชเชกเซ เชฐเชพเชเชคเซเช เชจเชฅเซ เชเซ เชคเซเชจเซ เชเชเชเช เชเชพเชฒเซ เชฐเชพเชเชตเชพ เชฎเชพเชเซ เชฐเชพเชน เชเซเชตเชพเชจเซ เชเชฐเซเชฐ เชนเซเชฏ. เช เชจเซ เชเซเชฏเชพเชฐเซ เชคเซ เชเชเชเช เชเชฐเซ เชเซ, เชคเซเชฏเชพเชฐเซ เชคเซ เชคเซเชจเชพ เช เชฎเชฒเชจเซ เชซเชฐเซเชฅเซ เชถเชฐเซ เชเชฐเซ เชเซ (เชชเชฐเชเชคเซ เชคเซ เช เชฅเซเชฐเซเชก เชชเชฐ เชเชฐเซเชฐเซ เชจเชฅเซ!). เช เชฎเชพเชฐเชพ เชเชฟเชธเซเชธเชพเชฎเชพเช, เช เชฎเซ เชเชพเชเชเซ เชฎเชพเชเซ เชฐเชพเชน เชเซเชเชถเซเช.
SemaphoreSlim
เช เชฎเชพเชเซ เชเซ WaitAsync()
เชชเชฆเซเชงเชคเชฟ เช
เชนเซเช เช เชชเซเชเชฐเซเชจเชจเซ เชเชชเชฏเซเช เชเชฐเซเชจเซ เช
เชฎเชฒเซเชเชฐเชฃ เชเซ.
// ะะฐะฟััะบ ัะฐะบะพะน ะถะต, ะบะฐะบ ัะฐะฝััะต. ะะดะต-ะฝะธะฑัะดั ะฒ ะฟัะพะณัะฐะผะผะต:
Task.Run(() => Run(i, cancelTokenSource.Token));
// ะะฐะฟััะบ ัะธะปะพัะพัะฐ.
// ะะปััะตะฒะพะต ัะปะพะฒะพ async -- ะบะพะผะฟะธะปััะพั ััะฐะฝัะปะธััะตั ััะพั ะผะตัะพั ะฒ ะฐัะธะฝั
ัะพะฝะฝัะน.
public async Task Run(int i, CancellationToken token)
{
while (true)
{
// await -- ะฑัะดะตะผ ะพะถะธะดะฐัั ะบะฐะบะพะณะพ-ัะพ ัะพะฑััะธั.
await TakeForks(i);
// ะะพัะปะต await, ะฟัะพะดะพะปะถะตะฝะธะต ะฒะพะทะผะพะถะฝะพ ะฒ ะดััะณะพะผ ะฟะพัะพะบะต.
eatenFood[i] = (eatenFood[i] + 1) % (int.MaxValue - 1);
// ะะพะถะตั ะฑััั ะฝะตัะบะพะปัะบะพ ัะพะฑััะธะน ะดะปั ะพะถะธะดะฐะฝะธั.
await PutForks(i);
Think(i);
if (token.IsCancellationRequested) break;
}
}
async Task TakeForks(int i)
{
bool hasForks = false;
while (!hasForks)
{
// ะะทะฐะธะผะพะธัะบะปััะฐััะธะน ะดะพัััะฟ ะบ ััะพะปั:
await _tableSemaphore.WaitAsync();
if (forks[Left(i)] == 0 && forks[Right(i)] == 0)
{
forks[Left(i)] = i+1;
forks[Right(i)] = i+1;
hasForks = true;
}
_tableSemaphore.Release();
// ะัะดะตะผ ะพะถะธะดะฐัั, ััะพะฑั ัะพัะตะด ะฟะพะปะพะถะธะป ะฒะธะปะบะธ:
if (!hasForks)
await _philosopherSemaphores[i].WaitAsync();
}
}
// ะะดะตะผ ะดะพัััะฟะฐ ะบ ััะพะปั ะธ ะบะปะฐะดะตะผ ะฒะธะปะบะธ.
async Task PutForks(int i)
{
await _tableSemaphore.WaitAsync();
forks[Left(i)] = 0;
// "ะัะพะฑัะดะธัั" ัะพัะตะดะตะน, ะตัะปะธ ะพะฝะธ "ัะฟะฐะปะธ".
_philosopherSemaphores[LeftPhilosopher(i)].Release();
forks[Right(i)] = 0;
_philosopherSemaphores[RightPhilosopher(i)].Release();
_tableSemaphore.Release();
}
เชธเชพเชฅเซ เชชเชฆเซเชงเชคเชฟ async
/ await
เชเช เชฎเซเชถเซเชเซเชฒ เชฐเชพเชเซเชฏ เชฎเชถเซเชจเชฎเชพเช เช
เชจเซเชตเชพเชฆเชฟเชค เชฅเชพเชฏ เชเซ เชเซ เชคเชฐเชค เช เชคเซเชจเซ เชเชเชคเชฐเชฟเช เชชเชฐเชค เชเชฐเซ เชเซ Task
. เชคเซเชจเชพ เชฆเซเชตเชพเชฐเชพ, เชคเชฎเซ เชชเชฆเซเชงเชคเชฟ เชชเซเชฐเซเชฃ เชฅเชตเชพเชจเซ เชฐเชพเชน เชเซเช เชถเชเซ เชเซ, เชคเซเชจเซ เชฐเชฆ เชเชฐเซ เชถเชเซ เชเซ เช
เชจเซ เชฌเชพเชเซเชจเซเช เชฌเชงเซเช เชเซ เชคเชฎเซ เชเชพเชฐเซเชฏ เชธเชพเชฅเซ เชเชฐเซ เชถเชเซ เชเซ. เชชเชฆเซเชงเชคเชฟเชจเซ เช
เชเชฆเชฐ, เชฐเชพเชเซเชฏ เชฎเชถเซเชจ เช
เชฎเชฒเชจเซ เชจเชฟเชฏเชเชคเซเชฐเชฟเชค เชเชฐเซ เชเซ. เชฌเซเชเชฎ เชฒเชพเชเชจ เช เชเซ เชเซ เชเซ เชคเซเชฏเชพเช เชเซเช เชตเชฟเชฒเชเชฌ เชจ เชนเซเชฏ, เชคเซ เช
เชฎเชฒ เชธเชฟเชเชเซเชฐเชจเชธ เชเซ, เช
เชจเซ เชเซ เชคเซเชฏเชพเช เชเซ, เชคเซ เชชเชเซ เชฅเซเชฐเซเชก เชชเซเชฐเชเชพเชถเชฟเชค เชฅเชพเชฏ เชเซ. เชเชจเซ เชตเชงเซ เชธเชพเชฐเซ เชฐเซเชคเซ เชธเชฎเชเชตเชพ เชฎเชพเชเซ, เช เชฐเชพเชเซเชฏ เชฎเชถเซเชจเชจเซ เชเซเชตเซเช เชตเชงเซ เชธเชพเชฐเซเช เชเซ. เชคเชฎเซ เชเชฎเชพเชเชฅเซ เชธเชพเชเชเชณเซ เชฌเชจเชพเชตเซ เชถเชเซ เชเซ async
/ await
เชชเชฆเซเชงเชคเชฟเช
เชเชพเชฒเซ เชชเชฐเซเชเซเชทเชฃ เชเชฐเซเช. 100 เชฒเซเชเชฟเชเชฒ เชเซเชฐเซ, 4 เชธเซเชเชจเซเชก เชธเชพเชฅเซ เชฎเชถเซเชจ เชชเชฐ 8 เชซเชฟเชฒเซเชธเซเชซเชฐเชจเซเช เชเชพเชฎ. เชฎเซเชจเชฟเชเชฐ เชธเชพเชฅเซเชจเซเช เชชเชพเชเชฒเซเช เชธเซเชฒเซเชฏเซเชถเชจ เชซเชเซเชค เชชเซเชฐเชฅเชฎ 4 เชฅเซเชฐเซเชกเซ เชเชฒเชพเชตเชคเซเช เชนเชคเซเช เช เชจเซ เชฌเชพเชเซเชจเซเช เชฌเชฟเชฒเชเซเชฒ เชเชพเชฒเชคเซเช เชจเชฅเซ. เช 4 เชฅเซเชฐเซเชกเซเชฎเชพเชเชฅเซ เชฆเชฐเซเช เชฒเชเชญเช 2ms เชฎเชพเชเซ เชจเชฟเชทเซเชเซเชฐเชฟเชฏ เชนเชคเซ. เช เชจเซ async/await เชธเซเชฒเซเชฏเซเชถเชจ เชฆเชฐเซเช 100 เชธเซเชเชจเซเชกเชจเซ เชธเชฐเซเชฐเชพเชถ เชชเซเชฐเชคเซเชเซเชทเชพ เชธเชพเชฅเซ, เชคเชฎเชพเชฎ 6.8 เชฐเชจ เชเชฐเซ เชเซ. เช เชฒเชฌเชคเซเชค, เชตเชพเชธเซเชคเชตเชฟเช เชธเชฟเชธเซเชเชฎเซเชฎเชพเช, 6 เชธเซเชเชจเซเชก เชฎเชพเชเซ เชจเชฟเชทเซเชเซเชฐเชฟเชฏ เช เชธเซเชตเซเชเชพเชฐเซเชฏ เชเซ เช เชจเซ เชเชจเชพ เชเซเชตเซ เชเชฃเซ เชตเชฟเชจเชเชคเซเช เชชเชฐ เชชเซเชฐเชเซเชฐเชฟเชฏเชพ เชจ เชเชฐเชตเซ เชคเซ เชตเชงเซ เชธเชพเชฐเซเช เชเซ. เชฎเซเชจเชฟเชเชฐ เชธเชพเชฅเซเชจเซเช เชธเซเชฒเซเชฏเซเชถเชจ เชฌเชฟเชฒเชเซเชฒ เชฎเชพเชชเซ เชถเชเชพเชฏ เชคเซเชตเซเช เชจเชฅเซ.
เชจเชฟเชทเซเชเชฐเซเชท
เชเซเชฎ เชคเชฎเซ เช เชจเชพเชจเชพ เชเชฆเชพเชนเชฐเชฃเซเชฎเชพเชเชฅเซ เชเซเช เชถเชเซ เชเซ, .NET เชเชฃเชพ เชธเชฟเชเชเซเชฐเซเชจเชพเชเชเซเชถเชจ เชเชจเซเชธเซเชเซเชฐเชเซเชเซเชธเชจเซ เชธเชชเซเชฐเซเช เชเชฐเซ เชเซ. เชเซ เชเซ, เชคเซเชจเซ เชเชชเชฏเซเช เชเซเชตเซ เชฐเซเชคเซ เชเชฐเชตเซ เชคเซ เชนเชเชฎเซเชถเชพ เชธเซเชชเชทเซเช เชนเซเชคเซเช เชจเชฅเซ. เชฎเชจเซ เชเชถเชพ เชเซ เชเซ เช เชฒเซเช เชฎเชฆเชฆเชฐเซเชช เชนเชคเซ. เชนเชฎเชฃเชพเช เชฎเชพเชเซ, เช เช เชเชค เชเซ, เชชเชฐเชเชคเซ เชนเชเซ เชเชฃเซ เชฐเชธเชชเซเชฐเชฆ เชตเชธเซเชคเซเช เชฌเชพเชเซ เชเซ, เชเชฆเชพเชนเชฐเชฃ เชคเชฐเซเชเซ, เชฅเซเชฐเซเชก-เชธเซเชซ เชเชฒเซเชเซเชถเชจ, TPL เชกเซเชเชพเชซเซเชฒเซ, เชฐเชฟเชเชเซเชเชฟเชต เชชเซเชฐเซเชเซเชฐเชพเชฎเชฟเชเช, เชธเซเชซเซเชเชตเซเชฐ เชเซเชฐเชพเชจเซเชเซเชเซเชถเชจ เชฎเซเชกเชฒ, เชตเชเซเชฐเซ.
เชธเซเชคเซเชฐเซเชคเซ
- เชชเซเชฐเชตเชพเชน เชตเชฟเชเซเชฏเซเชฒเชพเชเชเซเชถเชจ:
เชเชจเซเชเชฐเชจเซเชธเซ เชตเชฟเชเซเชฏเซเชฒเชพเชเชเชฐ - MSDN:
เชฅเซเชฐเซเชกเซเชเช ,เช เชธเซเชฎเซเชณ เชชเซเชฐเซเชเซเชฐเชพเชฎเชฟเชเช เชชเซเชเชฐเซเชจ เช เชจเซ เชเชฃเชพ เช เชจเซเชฏ เช เชจเซเชฏ - [เชฐเชฟเชเซเชเชฐ] - CLR เชตเชพเชฏเชพ C#, เชเซเชซเชฐเซ เชฐเชฟเชเซเชเชฐ
- [เชเชฐเชฟเช เชฒเชฟเชชเชฐเซเช] -
เชฒเซเช เชตเชฟเชถเซ เชธเซเชฐเซเชค - เชเชฟเชคเซเชฐ - "เชคเชฒเชตเชพเชฐเซ เชตเชเซเชเซ เชจเซเชคเซเชฏ", เชเซ. เชธเซเชฎเชฟเชฐเชพเชกเชธเซเชเซ
เชธเซเชฐเซเชธ: www.habr.com