История изменений
Исправление 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()
Как-то так. Если я правильно понимаю.