Nga Kairangi Kairangi, Whakataetae .NET Papatonotanga ranei

Nga Kairangi Kairangi, Whakataetae .NET Papatonotanga ranei

Kia kite tatou me pehea te mahi o te hotaka whakarara i roto i te .Net, ma te whakamahi i te Philosophers Dining Problem hei tauira. Ko te mahere ko tenei, mai i te tukutahitanga o nga miro / tukanga, ki te tauira kaiwhakaari (i nga waahanga e whai ake nei). Ka whai hua pea te tuhinga mo te tangata i mohio tuatahi, hei whakahou ranei i to matauranga.

He aha rawa te mahi? Ka eke nga kaihurihuri ki te rahinga iti, ka tau te ture a Moore ki runga i te herenga o te tere o te marama, no reira ka kitea te pikinga o te tau, ka taea te hanga i etahi atu transistors. I te wa ano, kei te tipu haere te nui o nga raraunga, me te tumanako nga kaiwhakamahi ki te whakautu wawe mai i nga punaha. I roto i tenei ahuatanga, ka kore e whai hua te kaupapa "noa", ina kotahi te miro mahi. Me whakatika e koe te raruraru o te mahi tukutahi, tukutahi ranei. Ano, ko tenei raruraru kei nga taumata rereke: i te taumata o nga miro, i te taumata o nga tukanga, i te taumata o nga miihini i roto i te whatunga (nga punaha tohatoha). Kei a NET nga hangarau kounga teitei, kua whakamatauria i te waa mo te tere me te pai ki te whakaoti rapanga pera.

Whāinga

I tukuna e Edsger Dijkstra tenei raruraru ki ana akonga i te timatanga o te tau 1965. Ko te whakatakotoranga kua whakaritea e whai ake nei. He maha tonu (e rima) nga tohunga mohio me te maha o nga marau. Ka noho ratou ki te tepu porotaka, he marau kei waenganui i a ratou. Ka taea e nga tohunga whakaaro te kai mai i a ratou pereti kai kore mutunga, te whakaaro, te tatari ranei. Ki te kai i te tohunga, me tango e koe kia rua nga marau (ko te whakamutunga ka tohatoha te marau me te tuatahi). Ko te tango me te tuku marau he mahi motuhake e rua. Ka wahangu nga tohunga whakaaro katoa. Ko te mahi ko te kimi i te algorithm penei ka whakaaro katoa ratou ka ki tonu ahakoa i muri i te 54 tau.

Tuatahi, me ngana ki te whakaoti i tenei raru ma te whakamahi i te waahi tiritahi. Ka takoto nga marau ki runga i te teepu noa, ka tango noa nga tohunga whakaaro i a ratau ka whakahokia. I konei he raru mo te tukutahitanga, ahea te tango surebets? he aha mena kaore he marau? me etahi atu. Engari ko te tuatahi, me timata nga whakaaro.

Hei timata i nga miro, ka whakamahia e matou he puna miro puta noa Task.Run tikanga:

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);
}

I hangaia te puna miro hei arotau i te hanga miro me te whakakore. He tūtira kei tenei puna me nga mahi, ka hangaia, ka tangohia ranei e te CLR nga miro i runga i te maha o enei mahi. Kotahi puna mo nga AppDomains katoa. Ko tenei puna kia whakamahia tata tonu, na te mea. kaua e raruraru ki te hanga, ki te whakakore i nga miro, ki o raatau rarangi, me etahi atu. Ka taea te kore he puna, engari me whakamahi tika koe. Thread, he pai tenei mo nga keehi ka hiahia koe ki te whakarereke i te kaupapa matua o te miro, ina he roa te mahi, mo te miro Tuhinga o mua, etc.

I etahi atu kupu, System.Threading.Tasks.Task he rite tonu te karaehe Thread, engari me nga momo mea pai katoa: te kaha ki te whakahaere i tetahi mahi i muri i tetahi poraka o etahi atu mahi, whakahokia mai i nga mahi, he pai te aukati i a raatau, me etahi atu. me etahi atu hei tautoko i nga hanganga tukutahi / tatari (Task-based Asynchronous Pattern, syntactic sugar mo te tatari mo nga mahi IO). Ka korero tatou mo tenei i muri mai.

CancelationTokenSource i konei ka hiahiatia kia mutu te miro i te tohu o te miro karanga.

Nga Take Tukutahi

Nga Kai-whakaaro kua parea

Kaati, e mohio ana matou ki te hanga miro, me ngana ki te kai tina:

// Кто какие вилки взял. К примеру: 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();
    }
}

I konei ka ngana tatou ki te tango i te marau maui, katahi ka mau te marau matau, a ki te pai, katahi ka kai ka whakahokia. Ko te tango i tetahi marau he ngota, i.e. e rua nga miro kaore e taea te tango kotahi i te wa kotahi (he he: ka panui te tuatahi he kore utu te marau, ko te tuarua - ka mau te tuatahi, ka mau te tuarua). Mo tenei Interlocked.CompareExchange, me whakatinana me te tohutohu tukatuka (TSL, XCHG), e maukati ana i tetahi wahi mahara mo te panui me te tuhi raupapa ngota. A ko te SpinWait he rite ki te hanga while(true) anake me te iti "makutu" - ka mau te miro ki te tukatuka (Thread.SpinWait), engari i etahi wa ka whakawhiti te mana ki tetahi atu miro (Thread.Yeild) ka moe ranei (Thread.Sleep).

Engari kaore tenei otinga e mahi, na te mea ka araia nga rere (mo ahau i roto i te hekona) ka mau: ka mau nga tohunga katoa ki te marau maui, engari kaua ki te taha matau. Kei te huinga marau nga uara: 1 2 3 4 5.

Nga Kairangi Kairangi, Whakataetae .NET Papatonotanga ranei

I roto i te ahua, te aukati miro (mate). Kakariki - te mahi, te whero - te tukutahi, te hina - kei te moe te miro. Ko nga rhombuses e tohu ana i te wa tiimata o nga Mahi.

Te Hiakai o nga Kairangi

Ahakoa ehara i te mea e tika ana kia nui te whakaaro o te kai, engari ko te matekai ka mutu te whakaaro a te tangata. Me ngana ki te whakataurite i te ahuatanga o te matekai o nga miro i roto i to tatou raru. Ko te matekai ko te wa e rere ana te miro, engari karekau he mahi nui, ara, ko te matemate ano tenei, inaianei kaore te miro e moe, engari e kaha ana ki te rapu kai, engari karekau he kai. Hei karo i te aukati i nga wa katoa, ka whakahokia e matou te marau ki te kore e taea e taatau te tango i tetahi atu.

// То же что и в 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)
    );
}

Ko te mea nui mo tenei waehere ko te rua o nga tohunga mohio e wha ka wareware ki te tuku i o raatau marau maui. A ka kitea he nui ake te kai, ko etahi ka timata ki te hiakai, ahakoa he rite te kaupapa matua o nga miro. I konei kaore ratou i te tino matekai, na te mea. Ka whakahokia e nga tohunga whakaaro kino o ratou marau i etahi wa. Ko te ahua ka kai nga tangata pai e 5 nga wa iti iho i nga kai kino. Na he hapa iti i roto i te waehere ka arahi ki te heke o te mahi. Me mahara ano ki konei ka puta he ahuatanga onge ka mau nga tohunga katoa ki te marau maui, karekau he taha matau, ka tuu te taha maui, tatari, ka maui ano, aha atu. He matekai ano tenei ahuatanga, he rite tonu ki te mate. I rahua ahau ki te whakahoki ano. Kei raro nei he pikitia mo te ahuatanga e rua nga tohunga mohio kino i tango i nga marau e rua, e rua nga mea pai e hiakai ana.

Nga Kairangi Kairangi, Whakataetae .NET Papatonotanga ranei

I konei ka kite koe ka oho nga miro i etahi wa ka ngana ki te tiki rauemi. E rua o nga matua e wha kaore he mahi (kauwhata matomato kei runga).

Te Matenga o te Kaikauwhau

Kaati, ko tetahi atu raruraru ka taea te whakararu i te hakari whakahirahira a nga tohunga whakaaro, mena ka mate ohorere tetahi o ratou me nga marau i ona ringa (a ka pena tonu ratou). Na ka waiho nga hoa tata ki te kore kai. Ka taea e koe te whakaputa i tetahi tauira tauira mo tenei keehi, hei tauira, ka maka ki waho NullReferenceException i muri i te tango a te tohunga ki nga marau. Na, ma te ara, kaore e whakahaerea te tuunga me te waehere waea kaore e mau noa (mo tenei AppDomain.CurrentDomain.UnhandledException me etahi atu). Na reira, ka hiahiatia nga kaikawe hapa i roto i nga miro me te mutunga pai.

Ko te kaitiaki

Kaati, me pehea e whakaoti ai i tenei mate mate, te matekai, me te mate? Ka tukuna e matou kia kotahi anake te tohunga ki te eke ki nga marau, ka taapirihia te whakakorenga o nga miro mo tenei waahi. Me pehea te mahi? Mehemea e tu ana tetahi kaitarai i te taha o nga tohunga mohio, e whakaae ana ki tetahi tohunga ki te tango i nga marau. Me pehea tatou e mahi ai i tenei kaitaita me pehea te patai a nga tohunga ki a ia, he pai nga patai.

Ko te huarahi ngawari ko te wa ka patai noa nga tohunga ki te kaitaita kia uru atu ki nga marau. Ko era. Inaianei e kore nga tohunga e tatari mo te marau e tata ana, engari me tatari, ka patai atu ranei ki te kaiawhina. I te tuatahi, ka whakamahia e matou anake te Mokowā Kaiwhakamahi mo tenei, kaore matou e whakamahi i nga aukati ki te karanga i nga tikanga mai i te kernel (mo ratou i raro nei).

Nga otinga i te waahi kaiwhakamahi

I konei ka pera ano ta matou mahi ki te marau kotahi me nga tohunga whakaaro e rua, ka huri i te huringa ka tatari. Tena ko tenei ka waiho hei tohunga whakaaro katoa, me te mea he marau kotahi, i.e. ka taea te kii ko te tohunga anake i tango i tenei "marau koura" mai i te kaiwhangai ka kai. Mo tenei ka whakamahia e matou te 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 he aukati tenei, he rite tonu te korero while(true) { if (!lock) break; }, engari he nui ake te "makutu" atu i roto SpinWait (e whakamahia ana ki reira). Inaianei kua mohio ia ki te tatau i te hunga e tatari ana, ki te whakamoe iti, me etahi atu. me etahi atu. I te nuinga o te waa, ka taea e nga mea katoa te arotau. Engari me mahara tatou ko te huringa kaha tonu tenei e kai ana i nga rauemi tukatuka me te pupuri i te rere, ka mate te matekai mena ka riro tetahi o nga philosopho hei kaupapa matua atu i etahi atu, engari karekau he marau koura (Priority Inversion problem) . Na reira, ka whakamahia e matou mo nga huringa poto rawa atu i roto i te mahara tiritahi, kaore he waea-tuatoru, he raka kohanga, me etahi atu ohorere.

Nga Kairangi Kairangi, Whakataetae .NET Papatonotanga ranei

Te tuhi mo SpinLock. Ko nga awa kei te "whawhai" mo te marau koura. He rahunga - i te ahua, te waahi kua tohua. Kaore i te tino whakamahia nga matua: tata noa ki te 2/3 e enei miro e wha.

Ko tetahi atu otinga i konei ko te whakamahi anake Interlocked.CompareExchange me te tatari kaha ano e whakaatuhia ana i roto i te waehere i runga ake nei (i roto i nga tohunga hiakai), engari ko tenei, kua kiia ake nei, ka taea te arai ki te aukati.

i runga i Interlocked Me kï reira e kore anake CompareExchange, engari ano etahi atu tikanga mo te panui me te tuhi ngota. A, na roto i te tukuruatanga o te huringa, mena ka whai wa tetahi atu miro ki te whakarereke (panui 1, panui 2, tuhi 2, tuhi 1 he kino), ka taea te whakamahi mo nga huringa uaua ki te uara kotahi (Interlocked Anything tauira) .

Rongoa Aratau Kernel

Kia kore ai e moumou rawa nga rauemi i roto i te kopikopiko, kia kite tatou me pehea e taea ai te aukati i tetahi miro. Arā, ma te haere tonu i to tatou tauira, kia kite tatou me pehea e moe ai te kaiwhangai i te philosopho me te whakaara i a ia ina tika ana. Tuatahi, me titiro me pehea te mahi ma te aratau kernel o te punaha whakahaere. Ko nga hanganga katoa kei reira he puhoi ake i era i te waahi kaiwhakamahi. He maha nga wa ka puhoi, hei tauira AutoResetEvent pea 53 nga wa poto ake SpinLock [Richter]. Engari ma to raatau awhina, ka taea e koe te tukutahi i nga tukanga puta noa i te punaha, whakahaere, kaore ranei.

Ko te hanga taketake i konei ko te semaphore i whakaarohia e Dijkstra neke atu i te haurua rau tau ki muri. Ko te semaphore, he mea noa, he tauoti totika e whakahaerehia ana e te punaha, me nga mahi e rua ki runga, te pikinga me te whakaheke. Ki te kore e heke, kore, ka aukatihia te miro waea. Ina whakanuia te tau e etahi atu miro/tukatuka kaha, ka pekehia nga miro, ka whakahekehia ano te semaphore e te tau kua paahitia. Ka taea e tetahi te whakaaro ki nga tereina i roto i te pounamu me te semaphore. He maha nga hanganga .NET he rite te mahi: AutoResetEvent, ManualResetEvent, Mutex me ahau ano Semaphore. Ka whakamahia e matou AutoResetEvent, koinei te mea ngawari o enei hanganga: e rua noa nga uara 0 me te 1 (he teka, pono). Ko tana Tikanga WaitOne() ka aukati i te miro waea ki te 0 te uara, ki te 1, ka whakahekehia ki te 0 ka pekehia. He tikanga Set() ka piki ki te 1 ka tuku tetahi kaitarai ki roto, ka heke ano ki te 0. He rite ki te takahuri o raro.

Kia whakararu tatou i te otinga me te whakamahi i te raka mo ia tohunga, kaua mo te katoa i te wa kotahi. Ko era. Inaianei he maha nga philosopho i te wa kotahi, kaore i te kotahi. Engari ka aukati ano matou i te uru ki te teepu kia tika ai, kia karo i nga reihi (nga tikanga reihi), tango 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();
}

Kia mohio ai koe ki nga mea e tupu ana i konei, whakaarohia te keehi i kore ai te tohunga mohio ki te tango i nga marau, katahi ka penei ana mahi. Kei te tatari ia mo te uru atu ki te tepu. Ka whiwhi ia, ka ngana ia ki te tango i nga marau. Kaore i mahi. Ka hoatu te uru ki te tepu (whakakore tetahi). Ka haere i tana "hurihuri" (AutoResetEvent) (kei te tuwhera tuatahi). Ka uru ano ki te huringa, na te mea kahore ona marau. Ka ngana ia ki te tango, ka tu ki tana "hurihuri". Ko etahi hoa tata ki te taha matau, maui ranei, ka mutu te kai, ka iriti i to maatau tohunga, "ka whakatuwhera i tana takahuri." Ka tukuna e to maatau tohunga (ka kati i muri) mo te wa tuarua. Ka ngana ia mo te toru o nga wa ki te tango i nga marau. Waimarie. A ka tukuna e ia tana takahuri ki te kai.

Ina he hapa matapōkere i roto i taua waehere (kei te noho tonu), hei tauira, ka he te tautuhi i tetahi hoa tata, ka hangaia ranei te mea kotahi. AutoResetEvent mo te katoa (Enumerable.Repeat), katahi ka tatari nga tohunga mo nga kaihanga, no te mea Ko te rapu hapa i roto i taua waehere he mahi uaua. Ko tetahi atu raruraru mo tenei otinga ko te kore e kii karekau etahi philosopho e hiakai.

Rongoa Ranu

Kua tirohia e matou nga huarahi e rua mo te wa, i te wa e noho ana matou ki te aratau kaiwhakamahi me te kopikopiko, me te wa e aukati ana matou i te miro i roto i te pata. Ko te tikanga tuatahi he pai mo nga kati poto, ko te tuarua mo nga mea roa. I te nuinga o te wa me tatari mo te wa poto kia huri te taurangi i roto i te kohanga, ka aukati i te miro ina roa te tatari. Ka whakatinanahia tenei huarahi i roto i te mea e kiia ana. hanganga ranu. Anei nga hanga rite mo te aratau kernel, engari inaianei me te kopae aratau kaiwhakamahi: SemaphorSlim, ManualResetEventSlim etc. Ko te hoahoa tino rongonui i konei ko Monitor, no te mea i roto i te C # he rongonui rongonui lock wetereo. Monitor he rite tonu te ahua o te semaphore me te uara teitei o te 1 (mutex), engari me te tautoko mo te tatari i roto i te kopikopiko, te recursion, te tauira Taurangi Tikanga (kei runga ake i tera i raro), me etahi atu. Me titiro tatou ki tetahi otinga.

// Спрячем объект для Монитора от всех, чтобы без дедлоков.
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);
    }
}

I konei kei te aukati ano matou i te teepu katoa kia uru atu ki nga marau, engari inaianei kei te wetewete i nga miro katoa i te wa kotahi, kaua nga hoa tata ka mutu te kai. Ko era. tuatahi, ka kai tetahi, ka poraka i nga hoa tata, ka mutu tenei tangata, engari ka hiahia ki te kai ano i taua wa tonu, ka haere ki te aukati ka oho i ona hoa tata, na te mea. he iti ake tona wa tatari.

Koinei te huarahi e karo ai tatou i nga mate mate me te matekai o etahi tohunga. Ka whakamahia e matou he koropiko mo te tatari poto ka aukati i te miro mo te roa. Ko te wetewete i nga tangata katoa i te wa kotahi he puhoi ake i te mea ka wetewete te hoa tata, penei i te otinga me AutoResetEvent, engari kaua e nui te rereketanga, na te mea me noho nga miro ki te aratau kaiwhakamahi i te tuatahi.

У lock he ohorere kino te syntax. Tūtohu ki te whakamahi Monitor tika [Richter] [Eric Lippert]. Ko tetahi o ratou ko tera lock i waho i nga wa katoa Monitor, ahakoa he rereke, ka taea e tetahi atu miro te whakarereke i te ahuatanga mahara tahi. I roto i enei ahuatanga, he pai ake te haere ki te kati, ki te whakamutu ranei i te kaupapa. Ko tetahi atu ohorere ko te whakamahi a Monitor i nga poraka tukutahi (SyncBlock), kei roto i nga mea katoa. No reira, ki te kowhiria he ahanoa e kore e tika ana, ka ngawari noa iho koe ki te kati (hei tauira, ki te maukati koe i tetahi aho whakauru). Ka whakamahia e matou te mea huna tonu mo tenei.

Ko te tauira Taurangi Tikanga ka taea e koe te whakatinana i te tumanako mo etahi ahuatanga uaua. I roto i te .NET, kaore i oti, ki taku whakaaro, na te mea i roto i te ariā, me maha nga rarangi i runga i te maha o nga taurangi (penei i nga Miro Posix), kaua ki te waahi kotahi. Na ka taea e tetahi te hanga mo nga tohunga mohio katoa. Engari ahakoa i tenei ahua, ka taea e koe te whakaiti i te waehere.

maha philosopho ranei async / await

Kaati, inaianei ka taea e taatau te aukati i nga miro. Engari he aha mehemea he tokomaha o tatou philosopho? 100? 10000? Hei tauira, 100000 nga tono i tae mai ki te tūmau tukutuku. Ka nui ake te hanga i tetahi miro mo ia tono, na te mea na te maha o nga miro e kore e rere whakarara. Ka rere noa i te maha o nga waahanga arorau (e 4 aku). A ko etahi atu ka tango noa i nga rawa. Ko tetahi otinga mo tenei raru ko te tauira async / tatari. Ko tana whakaaro ko te mahi kaore e mau i te miro mena me tatari kia haere tonu tetahi mea. A, ka mahia e ia tetahi mea, ka timata ano tana mahi (engari kaore i runga i te miro kotahi!). I a maatau, ka tatari tatou mo te marau.

SemaphoreSlim kua mo tenei WaitAsync() tikanga. Anei he whakatinanatanga ma te whakamahi i tenei tauira.

// Запуск такой же, как раньше. Где-нибудь в программе:
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();
}

Tikanga me async / await kua whakamaoritia ki roto i te miihini ahua uaua ka whakahoki tonu mai i a roto Task. Na roto i te reira, ka taea e koe te tatari mo te otinga o te tikanga, whakakorehia, me era atu mea katoa ka taea e koe ki te Mahi. I roto i te tikanga, ka whakahaerehia e te miihini kawanatanga te mahi. Ko te rarangi o raro, ki te kore he whakaroa, katahi ka tukutahi te mahi, ki te mea kei reira, ka tukuna te miro. Mo te pai ake o te mohio ki tenei, he pai ake te titiro ki tenei miihini kawanatanga. Ka taea e koe te hanga mekameka mai i enei async / await tikanga.

Kia whakamatautau tatou. Mahi a 100 tohunga ki runga i tetahi miihini e 4 nga matua arorau, 8 hēkona. Ko te otinga o mua me te Aroturuki i whakahaere i nga miro tuatahi e 4 me te toenga kaore rawa i rere. Ia o enei miro e 4 i mangere mo te 2ms. Na te otinga async / tatari i rere katoa 100, me te tatari toharite o 6.8 hēkona ia. Ae ra, i roto i nga punaha tuuturu, kaore e whakaaetia mo te 6 hēkona he pai ake kia kaua e tukatuka i nga tono maha penei. Ko te otinga me te Aroturuki karekau rawa e tauine.

mutunga

Ka kite koe mai i enei tauira iti, kei te tautoko a NET i te maha o nga hanga tukutahi. Heoi, kaore i te maarama tonu me pehea te whakamahi. Te ti'aturi nei au i awhina tenei tuhinga. I tenei wa, koinei te mutunga, engari he maha tonu nga mea whakamere e toe ana, hei tauira, nga kohinga miro-haumaru, TPL Dataflow, Reactive programming, Software Transaction model, etc.

Rauemi

Source: will.com

Tāpiri i te kōrero