āĻāĻ¸ā§āĻ¨ āĻĻā§āĻāĻŋ āĻāĻŋāĻāĻžāĻŦā§ āĻ¸āĻŽāĻ¸āĻžāĻŽāĻ¯āĻŧāĻŋāĻ āĻāĻŦāĻ āĻ¸āĻŽāĻžāĻ¨ā§āĻ¤āĻ°āĻžāĻ˛ āĻĒā§āĻ°ā§āĻā§āĻ°āĻžāĻŽāĻŋāĻ .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
, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻ¸āĻŦ āĻ§āĻ°āĻŖā§āĻ° āĻ¸ā§āĻŦāĻŋāĻ§āĻžāĻ° āĻ¸āĻžāĻĨā§: āĻ
āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻāĻžāĻā§āĻ° āĻāĻāĻāĻŋ āĻŦā§āĻ˛āĻā§āĻ° āĻĒāĻ°ā§ āĻāĻāĻāĻŋ āĻāĻžāĻ¸ā§āĻ āĻāĻžāĻ˛āĻžāĻ¨ā§āĻ° āĻā§āĻˇāĻŽāĻ¤āĻž, āĻ¸ā§āĻā§āĻ˛āĻŋāĻā§ āĻĢāĻžāĻāĻļāĻ¨ āĻĨā§āĻā§ āĻĢāĻŋāĻ°āĻŋāĻ¯āĻŧā§ āĻĻā§āĻāĻ¯āĻŧāĻž, āĻ¸ā§āĻŦāĻŋāĻ§āĻžāĻŽāĻ¤ āĻŦāĻžāĻ§āĻž āĻĻā§āĻāĻ¯āĻŧāĻž āĻāĻŦāĻ āĻāĻ°āĻ āĻ
āĻ¨ā§āĻ āĻāĻŋāĻā§āĨ¤ āĻāĻ¤ā§āĻ¯āĻžāĻĻāĻŋāĨ¤ āĻāĻā§āĻ˛āĻŋāĻā§ āĻ
ā§āĻ¯āĻžāĻ¸āĻŋāĻā§āĻ/āĻāĻ¯āĻŧā§āĻ āĻāĻ¨āĻ¸ā§āĻā§āĻ°āĻžāĻāĻļāĻ¨ āĻ¸āĻŽāĻ°ā§āĻĨāĻ¨ āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻĒā§āĻ°āĻ¯āĻŧā§āĻāĻ¨ (āĻāĻžāĻ¸ā§āĻ-āĻāĻŋāĻ¤ā§āĻ¤āĻŋāĻ āĻ
ā§āĻ¯āĻžāĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻ¸ āĻĒā§āĻ¯āĻžāĻāĻžāĻ°ā§āĻ¨, āĻāĻāĻ āĻ
āĻĒāĻžāĻ°ā§āĻļāĻ¨ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ
āĻĒā§āĻā§āĻˇāĻž āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻ¸āĻŋāĻ¨āĻā§āĻ¯āĻžāĻāĻāĻŋāĻ āĻāĻŋāĻ¨āĻŋ)āĨ¤ āĻāĻŽāĻ°āĻž āĻĒāĻ°ā§ āĻāĻ āĻŦāĻŋāĻˇāĻ¯āĻŧā§ āĻāĻĨāĻž āĻšāĻŦā§.
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)
);
}
āĻāĻ āĻā§āĻĄ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§āĻ°ā§āĻŖ āĻŦāĻŋāĻˇāĻ¯āĻŧ āĻšāĻ˛ āĻ¯ā§ āĻāĻžāĻ°āĻāĻŋ āĻĻāĻžāĻ°ā§āĻļāĻ¨āĻŋāĻā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻĻā§āĻāĻāĻ¨ āĻ¤āĻžāĻĻā§āĻ° āĻŦāĻžāĻŽ āĻāĻžāĻāĻāĻž āĻ¨āĻŋāĻā§ āĻ°āĻžāĻāĻ¤ā§ āĻā§āĻ˛ā§ āĻ¯āĻžāĻ¨āĨ¤ āĻāĻŦāĻ āĻĻā§āĻāĻž āĻ¯āĻžāĻā§āĻā§ āĻ¯ā§ āĻ¤āĻžāĻ°āĻž āĻāĻ°āĻ āĻāĻžāĻŦāĻžāĻ° āĻāĻžāĻ¯āĻŧ, āĻ āĻ¨ā§āĻ¯āĻ°āĻž āĻā§āĻˇā§āĻ§āĻžāĻ°ā§āĻ¤ āĻšāĻ¤ā§ āĻļā§āĻ°ā§ āĻāĻ°ā§, āĻ¯āĻĻāĻŋāĻ āĻĨā§āĻ°ā§āĻĄāĻā§āĻ˛āĻŋāĻ° āĻāĻāĻ āĻ āĻā§āĻ°āĻžāĻ§āĻŋāĻāĻžāĻ° āĻ°āĻ¯āĻŧā§āĻā§āĨ¤ āĻāĻāĻžāĻ¨ā§ āĻ¤āĻžāĻ°āĻž āĻĒā§āĻ°ā§āĻĒā§āĻ°āĻŋ āĻā§āĻˇā§āĻ§āĻžāĻ°ā§āĻ¤ āĻ¨āĻ¯āĻŧ, āĻāĻžāĻ°āĻŖāĨ¤ āĻāĻžāĻ°āĻžāĻĒ āĻĻāĻžāĻ°ā§āĻļāĻ¨āĻŋāĻāĻ°āĻž āĻāĻāĻ¨āĻ āĻāĻāĻ¨āĻ āĻ¤āĻžāĻĻā§āĻ° āĻāĻžāĻāĻāĻž āĻĒāĻŋāĻāĻ¨ā§ āĻ°āĻžāĻā§āĨ¤ āĻĻā§āĻāĻž āĻ¯āĻžāĻā§āĻā§ āĻāĻžāĻ˛ā§ āĻŽāĻžāĻ¨ā§āĻˇ āĻāĻžāĻ°āĻžāĻĒā§āĻ° āĻā§āĻ¯āĻŧā§ āĻĒā§āĻ°āĻžāĻ¯āĻŧ ā§Ģ āĻā§āĻŖ āĻāĻŽ āĻāĻžāĻ¯āĻŧāĨ¤ āĻ¸ā§āĻ¤āĻ°āĻžāĻ āĻā§āĻĄā§ āĻāĻāĻāĻŋ āĻā§āĻ āĻ¤ā§āĻ°ā§āĻāĻŋ āĻāĻ°ā§āĻŽāĻā§āĻˇāĻŽāĻ¤āĻž āĻšā§āĻ°āĻžāĻ¸ā§āĻ° āĻĻāĻŋāĻā§ āĻ¨āĻŋāĻ¯āĻŧā§ āĻ¯āĻžāĻ¯āĻŧāĨ¤ āĻāĻāĻžāĻ¨ā§ āĻāĻāĻŋāĻ āĻ˛āĻā§āĻˇāĻŖā§āĻ¯āĻŧ āĻ¯ā§ āĻāĻāĻāĻŋ āĻŦāĻŋāĻ°āĻ˛ āĻĒāĻ°āĻŋāĻ¸ā§āĻĨāĻŋāĻ¤āĻŋ āĻ¸āĻŽā§āĻāĻŦ āĻ¯āĻāĻ¨ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻĻāĻžāĻ°ā§āĻļāĻ¨āĻŋāĻ āĻŦāĻžāĻŽ āĻāĻžāĻāĻāĻž āĻ¨ā§āĻ¯āĻŧ, āĻ¸ā§āĻāĻžāĻ¨ā§ āĻĄāĻžāĻ¨ āĻā§āĻ āĻ¨ā§āĻ, āĻ¤āĻžāĻ°āĻž āĻŦāĻžāĻŽāĻĻāĻŋāĻā§ āĻ°āĻžāĻā§āĻ¨, āĻ āĻĒā§āĻā§āĻˇāĻž āĻāĻ°ā§āĻ¨, āĻāĻŦāĻžāĻ° āĻŦāĻžāĻŽāĻāĻŋ āĻ¨ā§āĻ¨ āĻāĻ¤ā§āĻ¯āĻžāĻĻāĻŋāĨ¤ āĻāĻ āĻĒāĻ°āĻŋāĻ¸ā§āĻĨāĻŋāĻ¤āĻŋāĻ āĻ āĻ¨āĻžāĻšāĻžāĻ°, āĻ āĻ¨ā§āĻāĻāĻž āĻ āĻāĻ˛āĻžāĻŦāĻ¸ā§āĻĨāĻžāĻ° āĻŽāĻ¤ā§āĨ¤ āĻāĻŽāĻŋ āĻāĻāĻŋ āĻĒā§āĻ¨āĻ°āĻžāĻŦā§āĻ¤ā§āĻ¤āĻŋ āĻāĻ°āĻ¤ā§ āĻŦā§āĻ¯āĻ°ā§āĻĨ āĻšāĻ¯āĻŧā§āĻā§. āĻ¨ā§āĻā§ āĻāĻŽāĻ¨ āĻāĻāĻāĻŋ āĻĒāĻ°āĻŋāĻ¸ā§āĻĨāĻŋāĻ¤āĻŋāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻāĻŦāĻŋ āĻ¯ā§āĻāĻžāĻ¨ā§ āĻĻā§āĻāĻŋ āĻāĻžāĻ°āĻžāĻĒ āĻĻāĻžāĻ°ā§āĻļāĻ¨āĻŋāĻ āĻāĻāĻ¯āĻŧāĻ āĻāĻžāĻāĻāĻžāĻāĻžāĻŽāĻ āĻ¨āĻŋāĻ¯āĻŧā§āĻā§ āĻāĻŦāĻ āĻĻā§āĻāĻŋ āĻāĻžāĻ˛ āĻā§āĻˇā§āĻ§āĻžāĻ°ā§āĻ¤āĨ¤
āĻāĻāĻžāĻ¨ā§ āĻāĻĒāĻ¨āĻŋ āĻĻā§āĻāĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ āĻ¯ā§ āĻĨā§āĻ°ā§āĻĄāĻā§āĻ˛āĻŋ āĻŽāĻžāĻā§ āĻŽāĻžāĻā§ āĻā§āĻā§ āĻāĻ ā§ āĻāĻŦāĻ āĻ¸āĻāĻ¸ā§āĻĨāĻžāĻ¨ āĻĒā§āĻ¤ā§ āĻā§āĻˇā§āĻāĻž āĻāĻ°ā§āĨ¤ āĻāĻžāĻ°āĻāĻŋ āĻā§āĻ°ā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻĻā§āĻāĻŋ āĻāĻŋāĻā§āĻ āĻāĻ°ā§ āĻ¨āĻž (āĻāĻĒāĻ°ā§āĻ° āĻ¸āĻŦā§āĻ āĻā§āĻ°āĻžāĻĢ)āĨ¤
āĻāĻāĻāĻ¨ āĻĻāĻžāĻ°ā§āĻļāĻ¨āĻŋāĻā§āĻ° āĻŽā§āĻ¤ā§āĻ¯ā§
āĻ āĻŋāĻ āĻāĻā§, āĻāĻ°ā§āĻāĻāĻŋ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻ¯āĻž āĻĻāĻžāĻ°ā§āĻļāĻ¨āĻŋāĻāĻĻā§āĻ° āĻāĻāĻāĻŋ āĻŽāĻšāĻŋāĻŽāĻžāĻ¨ā§āĻŦāĻŋāĻ¤ āĻ¨ā§āĻļāĻā§āĻā§ āĻŦāĻžāĻ§āĻž āĻĻāĻŋāĻ¤ā§ āĻĒāĻžāĻ°ā§ āĻ¤āĻž āĻš'āĻ˛ āĻ¯āĻĻāĻŋ āĻ¤āĻžāĻĻā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻāĻāĻāĻ¨ āĻšāĻ āĻžā§ āĻ¤āĻžāĻ° āĻšāĻžāĻ¤ā§ āĻāĻžāĻāĻāĻž āĻ¨āĻŋāĻ¯āĻŧā§ āĻŽāĻžāĻ°āĻž āĻ¯āĻžāĻ¯āĻŧ (āĻāĻŦāĻ āĻ¤āĻžāĻ°āĻž āĻ¤āĻžāĻā§ āĻāĻāĻžāĻŦā§ āĻāĻŦāĻ° āĻĻā§āĻŦā§)āĨ¤ āĻ¤āĻžāĻ°āĻĒāĻ° āĻĒā§āĻ°āĻ¤āĻŋāĻŦā§āĻļā§āĻĻā§āĻ° āĻ°āĻžāĻ¤ā§āĻ° āĻāĻžāĻŦāĻžāĻ° āĻāĻžāĻĄāĻŧāĻžāĻ āĻāĻ˛ā§ āĻ¯āĻžāĻŦā§āĨ¤ āĻāĻĒāĻ¨āĻŋ āĻāĻ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§ āĻ¨āĻŋāĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻāĻĻāĻžāĻšāĻ°āĻŖ āĻā§āĻĄ āĻ¨āĻŋāĻ¯āĻŧā§ āĻāĻ¸āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨, āĻāĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§āĻĒ, āĻāĻāĻŋ āĻĢā§āĻ˛ā§ āĻĻā§āĻāĻ¯āĻŧāĻž āĻšāĻ¯āĻŧ 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 (mutex), āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻāĻāĻŋ āĻ˛ā§āĻĒā§ āĻ
āĻĒā§āĻā§āĻˇāĻž āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻ¸āĻŽāĻ°ā§āĻĨāĻ¨, āĻĒā§āĻ¨āĻ°āĻžāĻŦā§āĻ¤ā§āĻ¤āĻŋ, āĻāĻ¨ā§āĻĄāĻŋāĻļāĻ¨ āĻā§āĻ°āĻŋāĻ¯āĻŧā§āĻŦāĻ˛ āĻĒā§āĻ¯āĻžāĻāĻžāĻ°ā§āĻ¨ (āĻ¨ā§āĻā§ āĻāĻ°āĻ āĻŦā§āĻļāĻŋ), āĻāĻ¤ā§āĻ¯āĻžāĻĻāĻŋāĨ¤ āĻāĻ° āĻ¸āĻžāĻĨā§ āĻāĻāĻāĻŋ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ āĻĻā§āĻāĻž āĻ¯āĻžāĻāĨ¤
// ĐĄĐŋŅŅŅĐĩĐŧ ОйŅĐĩĐēŅ Đ´ĐģŅ ĐĐžĐŊиŅĐžŅĐ° ĐžŅ вŅĐĩŅ
, ŅŅОйŅ ĐąĐĩС Đ´ĐĩĐ´ĐģĐžĐēОв.
private readonly object _lock = new object();
// ĐŅĐĩĐŧŅ ĐžĐļидаĐŊиŅ ĐŋĐžŅĐžĐēĐ°.
private DateTime?[] _waitTimes = new DateTime?[philosophersAmount];
public void Run(int i, CancellationToken token)
{
while (true)
{
TakeForks(i);
eatenFood[i] = (eatenFood[i] + 1) % (int.MaxValue - 1);
PutForks(i);
Think(i);
if (token.IsCancellationRequested) break;
}
}
// ĐĐ°ŅĐĩ ŅĐģĐžĐļĐŊĐžĐĩ ŅŅĐģОвиĐĩ Đ´ĐģŅ Condition Variable ĐŋĐ°ŅŅĐĩŅĐŊĐ°.
bool CanIEat(int i)
{
// ĐŅĐģи ĐĩŅŅŅ виĐģĐēи:
if (forks[Left(i)] != 0 && forks[Right(i)] != 0)
return false;
var now = DateTime.Now;
// ĐĐžĐļĐĩŅ, ĐĩŅĐģи ŅĐžŅĐĩди ĐŊĐĩ йОĐģĐĩĐĩ ĐŗĐžĐģОдĐŊŅĐĩ, ŅĐĩĐŧ ŅĐĩĐēŅŅиК.
foreach(var p in new int[] {LeftPhilosopher(i), RightPhilosopher(i)})
if (_waitTimes[p] != null && now - _waitTimes[p] > now - _waitTimes[i])
return false;
return true;
}
void TakeForks(int i)
{
// ĐĐ°ĐšŅи в ĐĐžĐŊиŅĐžŅ. ĐĸĐž ĐļĐĩ ŅĐ°ĐŧĐžĐĩ: lock(_lock) {..}.
// ĐŅСŅваĐĩĐŧ вĐŊĐĩ try, ŅŅОйŅ вОСĐŧĐžĐļĐŊĐžĐĩ иŅĐēĐģŅŅĐĩĐŊиĐĩ вŅĐąŅĐ°ŅŅваĐģĐžŅŅ вŅŅĐĩ.
bool lockTaken = false;
Monitor.Enter(_lock, ref lockTaken);
try
{
_waitTimes[i] = DateTime.Now;
// Condition Variable ĐŋĐ°ŅŅĐĩŅĐŊ. ĐŅвОйОĐļĐ´Đ°ĐĩĐŧ ĐģĐžĐē, ĐĩŅĐģи ĐŊĐĩ вŅĐŋĐžĐģĐŊĐĩĐŊĐŊĐž
// ŅĐģĐžĐļĐŊĐžĐĩ ŅŅĐģОвиĐĩ. Đ ĐļĐ´ĐĩĐŧ ĐŋĐžĐēĐ° ĐēŅĐž-ĐŊийŅĐ´Ņ ŅĐ´ĐĩĐģĐ°ĐĩŅ Pulse / PulseAll.
while (!CanIEat(i))
Monitor.Wait(_lock);
forks[Left(i)] = i + 1;
forks[Right(i)] = i + 1;
_waitTimes[i] = null;
}
finally
{
if (lockTaken) Monitor.Exit(_lock);
}
}
void PutForks(int i)
{
// ĐĸĐž ĐļĐĩ ŅĐ°ĐŧĐžĐĩ: lock (_lock) {..}.
bool lockTaken = false;
Monitor.Enter(_lock, ref lockTaken);
try
{
forks[Left(i)] = 0;
forks[Right(i)] = 0;
// ĐŅвОйОдиŅŅ вŅĐĩ ĐŋĐžŅĐžĐēи в ĐžŅĐĩŅĐĩди ĐĐĐĄĐРвŅСОва Monitor.Exit.
Monitor.PulseAll(_lock);
}
finally
{
if (lockTaken) Monitor.Exit(_lock);
}
}
āĻāĻāĻžāĻ¨ā§ āĻāĻŽāĻ°āĻž āĻāĻŦāĻžāĻ° āĻāĻžāĻāĻāĻžāĻāĻžāĻŽāĻ āĻ ā§āĻ¯āĻžāĻā§āĻ¸ā§āĻ¸ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻĒā§āĻ°ā§ āĻā§āĻŦāĻŋāĻ˛āĻāĻŋāĻā§ āĻŦā§āĻ˛āĻ āĻāĻ°āĻāĻŋ, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻāĻ¨ āĻāĻŽāĻ°āĻž āĻāĻāĻŦāĻžāĻ°ā§ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻĨā§āĻ°ā§āĻĄ āĻāĻ¨āĻŦā§āĻ˛āĻ āĻāĻ°āĻāĻŋ, āĻāĻŦāĻ āĻā§āĻ āĻāĻžāĻāĻ¯āĻŧāĻž āĻļā§āĻˇ āĻāĻ°āĻ˛ā§ āĻĒā§āĻ°āĻ¤āĻŋāĻŦā§āĻļā§āĻĻā§āĻ° āĻ¨āĻ¯āĻŧāĨ¤ āĻ¸ā§āĻā§āĻ˛ā§. āĻĒā§āĻ°āĻĨāĻŽāĻ¤, āĻā§āĻ āĻāĻžāĻ¯āĻŧ āĻāĻŦāĻ āĻĒā§āĻ°āĻ¤āĻŋāĻŦā§āĻļā§āĻĻā§āĻ° āĻŦā§āĻ˛āĻ āĻāĻ°ā§, āĻāĻŦāĻ āĻ¯āĻāĻ¨ āĻā§āĻ āĻāĻāĻŋ āĻļā§āĻˇ āĻāĻ°ā§, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻāĻ¨āĻ āĻāĻŦāĻžāĻ° āĻā§āĻ¤ā§ āĻāĻžāĻ¯āĻŧ, āĻ¸ā§ āĻŦā§āĻ˛āĻāĻŋāĻāĻ¯āĻŧā§ āĻ¯āĻžāĻ¯āĻŧ āĻāĻŦāĻ āĻ¤āĻžāĻ° āĻĒā§āĻ°āĻ¤āĻŋāĻŦā§āĻļā§āĻĻā§āĻ° āĻāĻžāĻāĻŋāĻ¯āĻŧā§ āĻ¤ā§āĻ˛ā§, āĻāĻžāĻ°āĻŖāĨ¤ āĻ¤āĻžāĻ° āĻ āĻĒā§āĻā§āĻˇāĻžāĻ° āĻ¸āĻŽāĻ¯āĻŧ āĻāĻŽāĨ¤
āĻāĻāĻžāĻŦā§āĻ āĻāĻŽāĻ°āĻž āĻ
āĻāĻ˛āĻžāĻŦāĻ¸ā§āĻĨāĻž āĻāĻŦāĻ āĻāĻŋāĻā§ āĻĻāĻžāĻ°ā§āĻļāĻ¨āĻŋāĻā§āĻ° āĻ
āĻ¨āĻžāĻšāĻžāĻ° āĻāĻĄāĻŧāĻžāĻ¤ā§ āĻĒāĻžāĻ°āĻŋāĨ¤ āĻāĻŽāĻ°āĻž āĻāĻāĻāĻŋ āĻ¸āĻāĻā§āĻˇāĻŋāĻĒā§āĻ¤ āĻ
āĻĒā§āĻā§āĻˇāĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻāĻāĻāĻŋ āĻ˛ā§āĻĒ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻŋ āĻāĻŦāĻ āĻĻā§āĻ°ā§āĻ āĻāĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻĨā§āĻ°ā§āĻĄāĻāĻŋ āĻŦā§āĻ˛āĻ āĻāĻ°āĻŋāĨ¤ āĻ¸āĻāĻ˛āĻā§ āĻāĻāĻŦāĻžāĻ°ā§ āĻ
āĻŦāĻ°ā§āĻ§ āĻŽā§āĻā§āĻ¤ āĻāĻ°āĻž āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻĒā§āĻ°āĻ¤āĻŋāĻŦā§āĻļā§āĻā§ āĻ
āĻŦāĻ°ā§āĻ§ āĻŽā§āĻā§āĻ¤ āĻāĻ°āĻžāĻ° āĻā§āĻ¯āĻŧā§ āĻ§ā§āĻ°, āĻ¯ā§āĻŽāĻ¨āĻāĻŋ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨ā§ āĻ°āĻ¯āĻŧā§āĻā§ AutoResetEvent
, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻĨāĻā§āĻ¯ āĻŦāĻĄāĻŧ āĻšāĻāĻ¯āĻŧāĻž āĻāĻāĻŋāĻ¤ āĻ¨āĻ¯āĻŧ, āĻāĻžāĻ°āĻŖ āĻĨā§āĻ°ā§āĻĄāĻā§āĻ˛āĻŋ āĻĒā§āĻ°āĻĨāĻŽā§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ°āĻāĻžāĻ°ā§ āĻŽā§āĻĄā§ āĻĨāĻžāĻāĻ¤ā§ āĻšāĻŦā§āĨ¤
ĐŖ lock
āĻ¸āĻŋāĻ¨āĻā§āĻ¯āĻžāĻā§āĻ¸ā§ āĻŦāĻžāĻā§ āĻāĻŽāĻ āĻāĻā§āĨ¤ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻ¸ā§āĻĒāĻžāĻ°āĻŋāĻļ āĻāĻ°ā§āĻ¨ Monitor
āĻ¸āĻ°āĻžāĻ¸āĻ°āĻŋ [āĻ°āĻŋāĻāĻāĻžāĻ°] [āĻāĻ°āĻŋāĻ āĻ˛āĻŋāĻĒāĻžāĻ°ā§āĻ]āĨ¤ āĻ¤āĻžāĻĻā§āĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻāĻāĻāĻŋ āĻšāĻ˛ āĻ¯ā§ lock
āĻ¸āĻ°ā§āĻŦāĻĻāĻž āĻŦāĻžāĻāĻ°ā§ Monitor
, āĻāĻŽāĻ¨āĻāĻŋ āĻ¯āĻĻāĻŋ āĻāĻāĻāĻŋ āĻŦā§āĻ¯āĻ¤āĻŋāĻā§āĻ°āĻŽ āĻāĻŋāĻ˛, āĻ¯ā§ āĻā§āĻˇā§āĻ¤ā§āĻ°ā§ āĻ
āĻ¨ā§āĻ¯ āĻĨā§āĻ°ā§āĻĄ āĻāĻžāĻ āĻāĻ°āĻž āĻŽā§āĻŽāĻ°āĻŋ āĻ
āĻŦāĻ¸ā§āĻĨāĻž āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤ āĻāĻ āĻ§āĻ°āĻ¨ā§āĻ° āĻā§āĻˇā§āĻ¤ā§āĻ°ā§, āĻĒā§āĻ°āĻžāĻ¯āĻŧāĻ āĻ
āĻāĻ˛āĻžāĻŦāĻ¸ā§āĻĨāĻžāĻ¯āĻŧ āĻ¯āĻžāĻāĻ¯āĻŧāĻž āĻŦāĻž āĻā§āĻ¨āĻāĻāĻžāĻŦā§ āĻ¨āĻŋāĻ°āĻžāĻĒāĻĻā§ āĻĒā§āĻ°ā§āĻā§āĻ°āĻžāĻŽāĻāĻŋ āĻŦāĻ¨ā§āĻ§ āĻāĻ°āĻž āĻāĻžāĻ˛āĨ¤ āĻāĻ°ā§āĻāĻāĻŋ āĻāĻļā§āĻāĻ°ā§āĻ¯ āĻšāĻ˛ āĻ¯ā§ āĻŽāĻ¨āĻŋāĻāĻ° āĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻāĻā§āĻļāĻ¨ āĻŦā§āĻ˛āĻ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°ā§ (SyncBlock
), āĻ¯āĻž āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻŦāĻ¸ā§āĻ¤ā§āĻ¤ā§ āĻāĻĒāĻ¸ā§āĻĨāĻŋāĻ¤ āĻĨāĻžāĻā§āĨ¤ āĻ
āĻ¤āĻāĻŦ, āĻ¯āĻĻāĻŋ āĻāĻāĻāĻŋ āĻ
āĻ¨ā§āĻĒāĻ¯ā§āĻā§āĻ¤ āĻŦāĻ¸ā§āĻ¤ā§ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻāĻ¨ āĻāĻ°āĻž āĻšāĻ¯āĻŧ, āĻāĻĒāĻ¨āĻŋ āĻ¸āĻšāĻā§āĻ āĻāĻāĻāĻŋ āĻ
āĻāĻ˛āĻžāĻŦāĻ¸ā§āĻĨāĻž āĻĒā§āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ (āĻāĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§āĻĒ, āĻ¯āĻĻāĻŋ āĻāĻĒāĻ¨āĻŋ āĻāĻāĻāĻŋ āĻāĻ¨ā§āĻāĻžāĻ°ā§āĻ¨ āĻ¸ā§āĻā§āĻ°āĻŋāĻ āĻ˛āĻ āĻāĻ°ā§āĻ¨)āĨ¤ āĻāĻŽāĻ°āĻž āĻāĻ° āĻāĻ¨ā§āĻ¯ āĻ¸āĻ°ā§āĻŦāĻĻāĻž āĻ˛ā§āĻāĻžāĻ¨ā§ āĻŦāĻ¸ā§āĻ¤ā§ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻŋāĨ¤
āĻļāĻ°ā§āĻ¤ āĻĒāĻ°āĻŋāĻŦāĻ°ā§āĻ¤āĻ¨āĻļā§āĻ˛ āĻĒā§āĻ¯āĻžāĻāĻžāĻ°ā§āĻ¨ āĻāĻĒāĻ¨āĻžāĻā§ āĻāĻ°āĻ āĻ¸āĻāĻā§āĻˇāĻŋāĻĒā§āĻ¤āĻāĻžāĻŦā§ āĻāĻŋāĻā§ āĻāĻāĻŋāĻ˛ āĻ āĻŦāĻ¸ā§āĻĨāĻžāĻ° āĻĒā§āĻ°āĻ¤ā§āĻ¯āĻžāĻļāĻž āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨ āĻāĻ°āĻ¤ā§ āĻĻā§āĻ¯āĻŧāĨ¤ .NET-āĻ, āĻāĻāĻž āĻ āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ, āĻāĻŽāĻžāĻ° āĻŽāĻ¤ā§, āĻāĻžāĻ°āĻŖ āĻ¤āĻžāĻ¤ā§āĻ¤ā§āĻŦāĻŋāĻāĻāĻžāĻŦā§, āĻŦāĻŋāĻāĻŋāĻ¨ā§āĻ¨ āĻā§āĻ°āĻŋāĻ¯āĻŧā§āĻŦāĻ˛ā§ (āĻĒāĻ¸āĻŋāĻā§āĻ¸ āĻĨā§āĻ°ā§āĻĄā§āĻ° āĻŽāĻ¤ā§) āĻāĻāĻžāĻ§āĻŋāĻ āĻ¸āĻžāĻ°āĻŋ āĻĨāĻžāĻāĻž āĻāĻāĻŋāĻ¤, āĻāĻāĻāĻŋ āĻ˛ā§āĻā§ āĻ¨āĻ¯āĻŧāĨ¤ āĻ¤āĻžāĻšāĻ˛ā§ āĻāĻāĻāĻ¨ āĻāĻā§āĻ˛āĻŋ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻĻāĻžāĻ°ā§āĻļāĻ¨āĻŋāĻāĻĻā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĨ¤ āĻ¤āĻŦā§ āĻāĻ āĻĢāĻ°ā§āĻŽā§āĻ, āĻāĻāĻŋ āĻāĻĒāĻ¨āĻžāĻā§ āĻā§āĻĄ āĻāĻŽāĻžāĻ¤ā§ āĻĻā§āĻ¯āĻŧāĨ¤
āĻ
āĻ¨ā§āĻ āĻĻāĻžāĻ°ā§āĻļāĻ¨āĻŋāĻ āĻŦāĻž 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
. āĻāĻāĻŋāĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§, āĻāĻĒāĻ¨āĻŋ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻāĻŋ āĻ¸āĻŽā§āĻĒā§āĻ°ā§āĻŖ āĻšāĻāĻ¯āĻŧāĻžāĻ° āĻāĻ¨ā§āĻ¯ āĻ
āĻĒā§āĻā§āĻˇāĻž āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨, āĻāĻāĻŋ āĻŦāĻžāĻ¤āĻŋāĻ˛ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ āĻāĻŦāĻ āĻ
āĻ¨ā§āĻ¯ āĻ¸āĻŦāĻāĻŋāĻā§ āĻ¯āĻž āĻāĻĒāĻ¨āĻŋ āĻāĻžāĻ¸ā§āĻā§āĻ° āĻ¸āĻžāĻĨā§ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨āĨ¤ āĻĒāĻĻā§āĻ§āĻ¤āĻŋāĻ° āĻāĻŋāĻ¤āĻ°ā§, āĻ°āĻžāĻˇā§āĻā§āĻ°ā§āĻ¯āĻŧ āĻŽā§āĻļāĻŋāĻ¨ āĻŽā§āĻ¤ā§āĻ¯ā§āĻĻāĻ¨ā§āĻĄ āĻ¨āĻŋāĻ¯āĻŧāĻ¨ā§āĻ¤ā§āĻ°āĻŖ āĻāĻ°ā§āĨ¤ āĻ¨ā§āĻā§āĻ° āĻ˛āĻžāĻāĻ¨ āĻšāĻ˛ āĻ¯ā§ āĻ¯āĻĻāĻŋ āĻā§āĻ¨ āĻŦāĻŋāĻ˛āĻŽā§āĻŦ āĻ¨āĻž āĻšāĻ¯āĻŧ, āĻ¤āĻžāĻšāĻ˛ā§ āĻŽā§āĻ¤ā§āĻ¯ā§āĻĻāĻ¨ā§āĻĄāĻāĻŋ āĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻ¸ āĻšāĻ¯āĻŧ, āĻāĻŦāĻ āĻ¯āĻĻāĻŋ āĻĨāĻžāĻā§, āĻ¤āĻžāĻšāĻ˛ā§ āĻĨā§āĻ°ā§āĻĄāĻāĻŋ āĻĒā§āĻ°āĻāĻžāĻļ āĻāĻ°āĻž āĻšāĻ¯āĻŧāĨ¤ āĻāĻāĻŋ āĻāĻ°āĻ āĻāĻžāĻ˛āĻāĻžāĻŦā§ āĻŦā§āĻāĻžāĻ° āĻāĻ¨ā§āĻ¯, āĻāĻ āĻ°āĻžāĻˇā§āĻā§āĻ°ā§āĻ¯āĻŧ āĻŽā§āĻļāĻŋāĻ¨āĻāĻŋ āĻĻā§āĻāĻ¤ā§ āĻāĻžāĻ˛āĨ¤ āĻāĻĒāĻ¨āĻŋ āĻāĻā§āĻ˛ā§ āĻĨā§āĻā§ āĻā§āĻāĻ¨ āĻ¤ā§āĻ°āĻŋ āĻāĻ°āĻ¤ā§ āĻĒāĻžāĻ°ā§āĻ¨ async
/ await
āĻĒāĻĻā§āĻ§āĻ¤āĻŋ
āĻĒāĻ°ā§āĻā§āĻˇāĻž āĻāĻ°āĻž āĻ¯āĻžāĻāĨ¤ 100 āĻ˛āĻāĻŋāĻā§āĻ¯āĻžāĻ˛ āĻā§āĻ°, 4 āĻ¸ā§āĻā§āĻ¨ā§āĻĄ āĻ¸āĻš āĻāĻāĻāĻŋ āĻŽā§āĻļāĻŋāĻ¨ā§ 8 āĻāĻ¨ āĻĻāĻžāĻ°ā§āĻļāĻ¨āĻŋāĻā§āĻ° āĻāĻžāĻāĨ¤ āĻŽāĻ¨āĻŋāĻāĻ°ā§āĻ° āĻ¸āĻžāĻĨā§ āĻĒā§āĻ°ā§āĻŦāĻŦāĻ°ā§āĻ¤ā§ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨āĻāĻŋ āĻļā§āĻ§ā§āĻŽāĻžāĻ¤ā§āĻ° āĻĒā§āĻ°āĻĨāĻŽ 4āĻāĻŋ āĻĨā§āĻ°ā§āĻĄ āĻāĻžāĻ˛āĻŋāĻ¯āĻŧā§āĻāĻŋāĻ˛ āĻāĻŦāĻ āĻŦāĻžāĻāĻŋāĻā§āĻ˛āĻŋ āĻŽā§āĻā§āĻ āĻāĻ˛ā§āĻ¨āĻŋāĨ¤ āĻāĻ 4āĻāĻŋ āĻĨā§āĻ°ā§āĻĄā§āĻ° āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋ āĻĒā§āĻ°āĻžāĻ¯āĻŧ 2 āĻŽāĻŋāĻ˛āĻŋāĻŽāĻŋāĻāĻžāĻ°ā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¨āĻŋāĻˇā§āĻā§āĻ°āĻŋāĻ¯āĻŧ āĻāĻŋāĻ˛āĨ¤ āĻāĻŦāĻ āĻ ā§āĻ¯āĻžāĻ¸āĻŋāĻā§āĻ/āĻāĻ¯āĻŧā§āĻ āĻ¸āĻ˛āĻŋāĻāĻļāĻ¨āĻāĻŋ 100āĻāĻŋ āĻāĻ˛ā§, āĻ¯āĻžāĻ° āĻĒā§āĻ°āĻ¤āĻŋāĻāĻŋāĻ° āĻāĻĄāĻŧ āĻ āĻĒā§āĻā§āĻˇāĻž 6.8 āĻ¸ā§āĻā§āĻ¨ā§āĻĄāĨ¤ āĻ āĻŦāĻļā§āĻ¯āĻ, āĻŦāĻžāĻ¸ā§āĻ¤āĻŦ āĻ¸āĻŋāĻ¸ā§āĻā§āĻŽā§, 6 āĻ¸ā§āĻā§āĻ¨ā§āĻĄā§āĻ° āĻāĻ¨ā§āĻ¯ āĻ¨āĻŋāĻˇā§āĻā§āĻ°āĻŋāĻ¯āĻŧ āĻĨāĻžāĻāĻž āĻ āĻā§āĻ°āĻšāĻŖāĻ¯ā§āĻā§āĻ¯ āĻāĻŦāĻ āĻāĻ° āĻŽāĻ¤ā§ āĻāĻ¤āĻā§āĻ˛āĻŋ āĻ āĻ¨ā§āĻ°ā§āĻ§ āĻĒā§āĻ°āĻā§āĻ°āĻŋāĻ¯āĻŧāĻž āĻ¨āĻž āĻāĻ°āĻžāĻ āĻāĻžāĻ˛āĨ¤ āĻŽāĻ¨āĻŋāĻāĻ°ā§āĻ° āĻ¸āĻžāĻĨā§ āĻ¸āĻŽāĻžāĻ§āĻžāĻ¨āĻāĻŋ āĻŽā§āĻā§āĻ āĻ¸ā§āĻā§āĻ˛āĻ¯ā§āĻā§āĻ¯ āĻ¨āĻ¯āĻŧ āĻŦāĻ˛ā§ āĻĒā§āĻ°āĻŽāĻžāĻŖāĻŋāĻ¤ āĻšāĻ¯āĻŧā§āĻā§āĨ¤
āĻāĻĒāĻ¸āĻāĻšāĻžāĻ°
āĻāĻĒāĻ¨āĻŋ āĻāĻ āĻā§āĻ āĻāĻĻāĻžāĻšāĻ°āĻŖāĻā§āĻ˛āĻŋ āĻĨā§āĻā§ āĻĻā§āĻāĻ¤ā§ āĻĒāĻžāĻā§āĻā§āĻ¨, .NET āĻ āĻ¨ā§āĻāĻā§āĻ˛āĻŋ āĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻāĻā§āĻļāĻ¨ āĻāĻ āĻ¨ āĻ¸āĻŽāĻ°ā§āĻĨāĻ¨ āĻāĻ°ā§āĨ¤ āĻ¯āĻžāĻāĻšā§āĻ, āĻāĻŋāĻāĻžāĻŦā§ āĻ¤āĻžāĻĻā§āĻ° āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻāĻ°āĻ¤ā§ āĻšāĻŦā§ āĻ¤āĻž āĻ¸āĻŦāĻ¸āĻŽāĻ¯āĻŧ āĻ¸ā§āĻĒāĻˇā§āĻ āĻ¨āĻ¯āĻŧāĨ¤ āĻāĻŽāĻŋ āĻāĻ āĻ¨āĻŋāĻŦāĻ¨ā§āĻ§āĻāĻŋ āĻ¸āĻšāĻžāĻ¯āĻŧāĻ āĻāĻŋāĻ˛ āĻāĻļāĻž āĻāĻ°āĻŋ. āĻāĻĒāĻžāĻ¤āĻ¤, āĻāĻāĻžāĻ āĻļā§āĻˇ, āĻāĻŋāĻ¨ā§āĻ¤ā§ āĻāĻāĻ¨āĻ āĻ āĻ¨ā§āĻ āĻāĻāĻ°ā§āĻˇāĻŖā§āĻ¯āĻŧ āĻāĻŋāĻ¨āĻŋāĻ¸ āĻŦāĻžāĻāĻŋ āĻāĻā§, āĻ¯ā§āĻŽāĻ¨, āĻĨā§āĻ°ā§āĻĄ-āĻ¸ā§āĻĢ āĻāĻžāĻ˛ā§āĻāĻļāĻ¨, āĻāĻŋāĻĒāĻŋāĻāĻ˛ āĻĄā§āĻāĻžāĻĢā§āĻ˛ā§, āĻ°āĻŋāĻ ā§āĻ¯āĻžāĻāĻāĻŋāĻ āĻĒā§āĻ°ā§āĻā§āĻ°āĻžāĻŽāĻŋāĻ, āĻ¸āĻĢāĻāĻāĻ¯āĻŧā§āĻ¯āĻžāĻ° āĻ˛ā§āĻ¨āĻĻā§āĻ¨ āĻŽāĻĄā§āĻ˛ āĻāĻ¤ā§āĻ¯āĻžāĻĻāĻŋāĨ¤
āĻ¸ā§āĻ¤ā§āĻ°
- āĻĢā§āĻ˛ā§ āĻāĻŋāĻā§āĻ¯ā§āĻ¯āĻŧāĻžāĻ˛āĻžāĻāĻā§āĻļāĻ¨:
āĻāĻ¨āĻāĻžāĻ°ā§āĻ¨ā§āĻ¸āĻŋ āĻāĻŋāĻā§āĻ¯ā§āĻ¯āĻŧāĻžāĻ˛āĻžāĻāĻāĻžāĻ° - MSDN:
āĻĨā§āĻ°ā§āĻĄāĻŋāĻ ,āĻ ā§āĻ¯āĻžāĻ¸āĻŋāĻā§āĻā§āĻ°ā§āĻ¨āĻžāĻ¸ āĻĒā§āĻ°ā§āĻā§āĻ°āĻžāĻŽāĻŋāĻ āĻĒā§āĻ¯āĻžāĻāĻžāĻ°ā§āĻ¨ āĻāĻŦāĻ āĻ āĻ¨ā§āĻ āĻ āĻ¨ā§āĻ¯āĻžāĻ¨ā§āĻ¯ āĻāĻ āĻ āĻ˛āĨ¤ - [āĻ°āĻŋāĻāĻāĻžāĻ°] - C# āĻāĻ° āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§ CLR, Jeffrey Richter
- [āĻāĻ°āĻŋāĻ āĻ˛āĻŋāĻĒāĻžāĻ°ā§āĻ] -
āĻ¤āĻžāĻ˛āĻž āĻ¸āĻŽā§āĻĒāĻ°ā§āĻā§ āĻāĻ¤ā§āĻ¸ āĻā§āĻĄ - āĻāĻŦāĻŋ - "āĻ¤āĻ˛ā§āĻ¯āĻŧāĻžāĻ° āĻŽāĻ§ā§āĻ¯ā§ āĻ¨āĻžāĻ", āĻāĻŋ āĻ¸ā§āĻŽāĻŋāĻ°āĻžāĻĄāĻ¸ā§āĻāĻŋ
āĻāĻ¤ā§āĻ¸: www.habr.com