LINUX.ORG.RU

История изменений

Исправление dissident, (текущая версия) :

Не очень только понятно, чем это всё отличается в концепции от event loop?

Я понимаю это так. что Event Loop будет или однотрэдовая вроде (допустим DispatchMessage* внутри содержит switch (msg.type) и что-то делает):

while (true)
{
    msg = GetMessage();
    // это делает работу в том же трэде, что и loop
    // и может добавить новые Message в queue
    DispatchMessage(msg);
}

Или async много/дву/пулл-трэдовая (с callback’ами) вроде:

while (true)
{
    msg, calback = GetMessageWithCallback();
    // это делает работу в отдельном трэде или там
    // в одном из трэдов из трэд пула и может добавить новые
    // Message в queue
    DispatchMessageAsyncInNewThread(msg, callback);
}

Если мы добавим fibers, то получиться однотрэдовый loop с yield’ами, что позволит переключать stack между конкретными DispatchMessage, что-нибудь вроде:

while (true)
{
    msg = GetMessage();
    // это делает работу и может добавить новые Message
    // но обслуживание конкретных msg в switch (msg.type)
    // иногда делает yield, позволяя внешнему циклу идти
    // дальше и делать другую работу в том же трэде, что
    // и loop, но со своим stack'ом
    DispatchMessageFiber(msg); 
    yield(); // сюда еще можно всобачить
}

void DispatchMessageFiber(msg)
{
    switch (msg.type)
    {
        case SOME_TYPE: DoSomeType(); break;
        case SOME_OTHER_TYPE: DoSomeOtherType(); break;
        ...
    }
}

void DoSomeType()
{
    while (some_condition)
    {
        DoSomeTypeALittleBit();
        yield();
    }
}

// same for DoSomeOtherType()

Как-то так. Если я правильно понимаю.

PS Выше pseudocode.

PPS Я посмотрел «видосик» про boost::fibers: https://www.youtube.com/watch?v=e-NUmyBou8Q, но IMHO из-за того, что везде такие абстракции как boost::fibers::async труднее понять, что происходит, чем если бы был просто yield.

PPPS А да, весь смысл в том, что однотрэдовая loop однотрэдовая, многотредовая делает много context switch, а cooperative multitasking позволяет их не делать. Т.е. even loop был просто как пример, что и там можно корутины/файберы впихнуть.

Исправление dissident, :

Не очень только понятно, чем это всё отличается в концепции от event loop?

Я понимаю это так. что Event Loop будет или однотрэдовая вроде (допустим DispatchMessage* внутри содержит switch (msg.type) и что-то делает):

while (true)
{
    msg = GetMessage();
    // это делает работу в том же трэде, что и loop
    // и может добавить новые Message в queue
    DispatchMessage(msg);
}

Или async много/дву/пулл-трэдовая (с callback’ами) вроде:

while (true)
{
    msg, calback = GetMessageWithCallback();
    // это делает работу в отдельном трэде или там
    // в одном из трэдов из трэд пула и может добавить новые
    // Message в queue
    DispatchMessageAsyncInNewThread(msg, callback);
}

Если мы добавим fibers, то получиться однотрэдовый loop с yield’ами, что позволит переключать stack между конкретными DispatchMessage, что-нибудь вроде:

while (true)
{
    msg = GetMessage();
    // это делает работу и может добавить новые Message
    // но обслуживание конкретных msg в switch (msg.type)
    // иногда делает yield, позволяя внешнему циклу идти
    // дальше и делать другую работу в том же трэде, что
    // и loop, но со своим stack'ом
    DispatchMessageFiber(msg); 
    yield(); // сюда еще можно всобачить
}

void DispatchMessageFiber(msg)
{
    switch (msg.type)
    {
        case SOME_TYPE: DoSomeType(); break;
        case SOME_OTHER_TYPE: DoSomeOtherType(); break;
        ...
    }
}

void DoSomeType()
{
    while (some_condition)
    {
        DoSomeTypeALittleBit();
        yield();
    }
}

// same for DoSomeOtherType()

Как-то так. Если я правильно понимаю.

PS Выше pseudocode.

PPS Я посмотрел «видосик» про boost::fibers: https://www.youtube.com/watch?v=e-NUmyBou8Q, но IMHO из-за того, что везде такие абстракции как boost::fibers::async труднее понять, что происходит, чем если бы был просто yield.

Исправление dissident, :

Не очень только понятно, чем это всё отличается в концепции от event loop?

Я понимаю это так. что Event Loop будет или однотрэдовая вроде (допустим DispatchMessage* внутри содержит switch (msg.type) и что-то делает):

while (true)
{
    msg = GetMessage();
    // это делает работу в том же трэде, что и loop
    // и может добавить новые Message в queue
    DispatchMessage(msg);
}

Или async много/дву/пулл-трэдовая (с callback’ами) вроде:

while (true)
{
    msg, calback = GetMessageWithCallback();
    // это делает работу в отдельном трэде или там
    // в одном из трэдов из трэд пула и может добавить новые
    // Message в queue
    DispatchMessageAsyncInNewThread(msg, callback);
}

Если мы добавим fibers, то получиться однотрэдовый loop с yield’ами, что позволит переключать stack между конкретными DispatchMessage, что-нибудь вроде:

while (true)
{
    msg = GetMessage();
    // это делает работу и может добавить новые Message
    // но обслуживание конкретных msg в switch (msg.type)
    // иногда делает yield, позволяя внешнему циклу идти
    // дальше и делать другую работу в том же трэде, что
    // и loop, но со своим stack'ом
    DispatchMessageFiber(msg); 
    yield(); // сюда еще можно всобачить
}

void DispatchMessageFiber(msg)
{
    switch (msg.type)
    {
        case SOME_TYPE: DoSomeType(); break;
        case SOME_OTHER_TYPE: DoSomeOtherType(); break;
        ...
    }
}

void DoSomeType()
{
    while (some_condition)
    {
        DoSomeTypeALittleBit();
        yield();
    }
}

// same for DoSomeOtherType()

Как-то так. Если я правильно понимаю.

PS Выше pseudocode.

PPS Я посмотрел «видосик» про boost::fibers: https://www.youtube.com/watch?v=e-NUmyBou8Q, но IMHO из-за того, что везде такие абстракции как boost::fiber::async труднее понять, что происходит, чем если бы был просто yield.

Исходная версия dissident, :

Не очень только понятно, чем это всё отличается в концепции от event loop?

Я понимаю это так. что Event Loop будет или однотрэдовая вроде (допустим DispatchMessage* внутри содержит switch (msg.type) и что-то делает):

while (true)
{
    msg = GetMessage();
    // это делает работу в том же трэде, что и loop
    // и может добавить новые Message в queue
    DispatchMessage(msg);
}

Или async много/дву/пулл-трэдовая (с callback’ами) вроде:

while (true)
{
    msg, calback = GetMessageWithCallback();
    // это делает работу в отдельном трэде или там
    // в одном из трэдов из трэд пула и может добавить новые
    // Message в queue
    DispatchMessageAsyncInNewThread(msg, callback);
}

Если мы добавим fibers, то получиться однотрэдовый loop с yield’ами, что позволит переключать stack между конкретными DispatchMessage, что-нибудь вроде:

while (true)
{
    msg = GetMessage();
    // это делает работу и может добавить новые Message
    // но обслуживание конкретных msg в switch (msg.type)
    // иногда делает yield, позволяя внешнему циклу идти
    // дальше и делать другую работу в том же трэде, что
    // и loop, но со своим stack'ом
    DispatchMessageFiber(msg); 
    yield(); // сюда еще можно всобачить
}

void DispatchMessageFiber(msg)
{
    switch (msg.type)
    {
        case SOME_TYPE: DoSomeType(); break;
        case SOME_OTHER_TYPE: DoSomeOtherType(); break;
        ...
    }
}

void DoSomeType()
{
    while (some_condition)
    {
        DoSomeTypeALittleBit();
        yield();
    }
}

// same for DoSomeOtherType()

Как-то так. Если я правильно понимаю.