LINUX.ORG.RU

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

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

я посмотрел по диагонали

Вот IMHO тут надо не по диагонали. И уж точно не вики. У нас, кстати, в институте препод был, который говорил, что если ему кто-нибудь википедию процитирует в работе или ответе, то сразу 2 поставит.

тебе там и стек разрисуют, что на нем хранится, и как переключается контекст покажут. чтобы его переключить надо спасти все регистры на текущий стек, и восстановить все регистры со стека той корутины, или треда, куда надо переключиться.

Это не отвечает на вопрос, что именно необходимо, чтобы превратить безстэковую корутину в волокно (fiber), кроме шедулера и возможности его выбрать, что можно легко дописать руками (псевдо-c++ и с захардкоженным «шедулером»):

queue<function<void(int, int)>> queue;

void coroutine(int id,
               int count,
               function<void(int,int)> next = function<void(int,int)>())
{
    while (count--)
    {
       cout << "id: " << id << ", count: " << count << endl;
       co_yield();
    }

    if (next)
    {
        queue.push(next);
    }
}

// named after order of start of execution
auto cor1 = bind(coroutine, 1, 42);
auto cor3 = bind(coroutine, 3, 43);
// these two add another coroutine (cor3) in it's body (next)
auto cor2 = bind(coroutine, 2, 44, cor3);
auto cor4 = bind(coroutine, 4, 45, cor3);

queue.push(cor1);
queue.push(cor2);

// simple "scheduler" for current thread, just a loop
// (should be in a separate thread, but for simplicity,
//  for the sake of this simple example, it is in the
//  same thread as the main thread and, before starting
//  it, some coroutines are already added (cor1 and cor2)
//  to make it all go round)
while (!finished) // assume some other thread sets this flag
{
    while (queue.empty() && !finished)
    {   
        co_yield();
    }

    if (!finished)
    {
        auto cor = queue.front();
        queue.pop();
        cor();
    }
}

IMHO этого недостаточно для полноценных волокон. Особенно если добавить какие-нибудь co_await (чтобы cor2 и cor4 зависели от выполнения cor3 при помощи co_await, а не просто закидывали их в queue).

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

я посмотрел по диагонали

Вот IMHO тут надо не по диагонали. И уж точно не вики. У нас, кстати, в институте препод был, который говорил, что если ему кто-нибудь википедию процитирует в работе или ответе, то сразу 2 поставит.

тебе там и стек разрисуют, что на нем хранится, и как переключается контекст покажут. чтобы его переключить надо спасти все регистры на текущий стек, и восстановить все регистры со стека той корутины, или треда, куда надо переключиться.

Это не отвечает на вопрос, что именно необходимо, чтобы превратить безстэковую корутину в волокно (fiber), кроме шедулера и возможности его выбрать, что можно легко дописать руками (псевдо-c++ и с захардкоженным «шедулером»):

queue<function<void(int, int)>> queue;

void coroutine(int id,
               int count,
               function<void(int,int)> next = function<void(int,int)>())
{
    while (count--)
    {
       cout << "id: " << id << ", count: " << count << endl;
       co_yield();
    }

    if (next)
    {
        queue.push(next);
    }
}

// named after order of start of execution
auto cor1 = bind(coroutine, 1, 42);
auto cor3 = bind(coroutine, 3, 43);
// these two add another coroutine (cor3) in it's body (next)
auto cor2 = bind(coroutine, 2, 44, cor3);
auto cor4 = bind(coroutine, 4, 45, cor3);

queue.push(cor1);
queue.push(cor2);

// simple "scheduler" for current thread, just a loop
// (should be in a separate thread, but for simplicity,
//  for the sake of this simple example, it is in the
//  same thread as the main thread and before starting
//  it some coroutines are already added (cor1 and cor2)
//  to make it all go round)
while (!finished) // assume some other thread sets this flag
{
    while (queue.empty() && !finished)
    {   
        co_yield();
    }

    if (!finished)
    {
        auto cor = queue.front();
        queue.pop();
        cor();
    }
}

IMHO этого недостаточно для полноценных волокон. Особенно если добавить какие-нибудь co_await (чтобы cor2 и cor4 зависели от выполнения cor3 при помощи co_await, а не просто закидывали их в queue).

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

я посмотрел по диагонали

Вот IMHO тут надо не по диагонали. И уж точно не вики. У нас, кстати, в институте препод был, который говорил, что если ему кто-нибудь википедию процитирует в работе или ответе, то сразу 2 поставит.

тебе там и стек разрисуют, что на нем хранится, и как переключается контекст покажут. чтобы его переключить надо спасти все регистры на текущий стек, и восстановить все регистры со стека той корутины, или треда, куда надо переключиться.

Это не отвечает на вопрос, что именно необходимо, чтобы превратить безстэковую корутину в волокно (fiber), кроме шедулера и возможности его выбрать, что можно легко дописать руками (псевдо-c++ и с захардкоженным «шедулером»):

queue<function<void(int, int)>> queue;

void coroutine(int id,
               int count,
               function<void(int,int)> next = function<void(int,int)>())
{
    while (count--)
    {
       cout << "id: " << id << ", count: " << count << endl;
       co_yield();
    }

    if (next)
    {
        queue.push(next);
    }
}

// named after order of start of execution
auto cor1 = bind(coroutine, 1, 42);
auto cor3 = bind(coroutine, 3, 43);
// these two add another coroutine (cor3) in it's body (next)
auto cor2 = bind(coroutine, 2, 44, cor3);
auto cor4 = bind(coroutine, 4, 45, cor3);

queue.push(cor1);
queue.push(cor2);

// simple "scheduler" for current thread, just a loop
// (should be in a separate thread, but for simplicity,
//  for the sake of this simple example, it is in the
//  same thread as the main thread and before starting
//  it,  some coroutines are already added (cor1 and cor2)
//  to make it all go round)
while (!finished) // assume some other thread sets this flag
{
    while (queue.empty() && !finished)
    {   
        co_yield();
    }

    if (!finished)
    {
        auto cor = queue.front();
        queue.pop();
        cor();
    }
}

IMHO этого недостаточно для полноценных волокон. Особенно если добавить какие-нибудь co_await (чтобы cor2 и cor4 зависели от выполнения cor3 при помощи co_await, а не просто закидывали их в queue).

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

я посмотрел по диагонали

Вот IMHO тут надо не по диагонали. И уж точно не вики. У нас, кстати, в институте препод был, который говорил, что если ему кто-нибудь википедию процитирует в работе или ответе, то сразу 2 поставит.

тебе там и стек разрисуют, что на нем хранится, и как переключается контекст покажут. чтобы его переключить надо спасти все регистры на текущий стек, и восстановить все регистры со стека той корутины, или треда, куда надо переключиться.

Это не отвечает на вопрос, что именно необходимо, чтобы превратить безстэковую корутину в волокно (fiber), кроме шедулера и возможности его выбрать, что можно легко дописать руками (псевдо-c++ и с захардкоженным «шедулером»):

queue<function<void(int, int)>> queue;

void coroutine(int id,
               int count,
               function<void(int,int)> next = function<void(int,int)>())
{
    while (count--)
    {
       cout << "id: " << id << ", count: " << count << endl;
       co_yield();
    }

    if (next)
    {
        queue.push(next);
    }
}

// named after order of start of execution
auto cor1 = bind(coroutine, 1, 42);
auto cor3 = bind(coroutine, 3, 43);
// these two add another coroutine (cor3) in it's body (next)
auto cor2 = bind(coroutine, 2, 44, cor3);
auto cor4 = bind(coroutine, 4, 45, cor3);

queue.push(cor1);
queue.push(cor2);

// simple "scheduler" for current thread, just a loop
// (should be in a separate thread, but for simplicity,
//  for the sake of this simple example, it is in the
//   same thread as the main thread and before starting
//  it,  some coroutines are already added (cor1 and cor2)
//  to make it all go round)
while (!finished) // assume some other thread sets this flag
{
    while (queue.empty() && !finished)
    {   
        co_yield();
    }

    if (!finished)
    {
        auto cor = queue.front();
        queue.pop();
        cor();
    }
}

IMHO этого недостаточно для полноценных волокон. Особенно если добавить какие-нибудь co_await (чтобы cor2 и cor4 зависели от выполнения cor3 при помощи co_await, а не просто закидывали их в queue).

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

я посмотрел по диагонали

Вот IMHO тут надо не по диагонали. И уж точно не вики. У нас, кстати, в институте препод был, который говорил, что если ему кто-нибудь википедию процитирует в работе или ответе, то сразу 2 поставит.

тебе там и стек разрисуют, что на нем хранится, и как переключается контекст покажут. чтобы его переключить надо спасти все регистры на текущий стек, и восстановить все регистры со стека той корутины, или треда, куда надо переключиться.

Это не отвечает на вопрос, что именно необходимо, чтобы превратить безстэковую корутину в волокно (fiber), кроме шедулера и возможности его выбрать, что можно легко дописать руками (псевдо-c++ и с захардкоженным «шедулером»):

queue<function<void(int, int)>> queue;

void coroutine(int id,
               int count,
               function<void(int,int)> next = function<void(int,int)>())
{
    while (count--)
    {
       cout << "id: " << id << ", count: " << count << endl;
       co_yield();
    }

    if (next)
    {
        queue.push(next);
    }
}

// named after order of start of execution
auto cor1 = bind(coroutine, 1, 42);
auto cor3 = bind(coroutine, 3, 43);
// these two add another coroutine (cor3) in it's body (next)
auto cor2 = bind(coroutine, 2, 44, cor3);
auto cor4 = bind(coroutine, 4, 45, cor3);

queue.push(cor1);
queue.push(cor2);

// simple "scheduler" for current thread, just a loop
// (should be in a separate thread, but for simplicity,
//  for the sake of this simple example, it is in the
/   thread as the main thread and before starting it,
//  some coroutines are already added (cor1 and cor2)
//  to make it all go round)
while (!finished) // assume some other thread sets this flag
{
    while (queue.empty() && !finished)
    {   
        co_yield();
    }

    if (!finished)
    {
        auto cor = queue.front();
        queue.pop();
        cor();
    }
}

IMHO этого недостаточно для полноценных волокон. Особенно если добавить какие-нибудь co_await (чтобы cor2 и cor4 зависели от выполнения cor3 при помощи co_await, а не просто закидывали их в queue).

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

я посмотрел по диагонали

Вот IMHO тут надо не по диагонали. И уж точно не вики. У нас, кстати, в институте препод был, который говорил, что если ему кто-нибудь википедию процитирует в работе или ответе, то сразу 2 поставит.

тебе там и стек разрисуют, что на нем хранится, и как переключается контекст покажут. чтобы его переключить надо спасти все регистры на текущий стек, и восстановить все регистры со стека той корутины, или треда, куда надо переключиться.

Это не отвечает на вопрос, что именно необходимо, чтобы превратить безстэковую корутину в волокно (fiber), кроме шедулера и возможности его выбрать, что можно легко дописать руками (псевдо-c++ и с захардкоженным «шедулером»):

queue<function<void(int, int)>> queue;

void coroutine(int id,
               int count,
               function<void(int,int)> next = function<void(int,int)>())
{
    while (count--)
    {
       cout << "id: " << id << ", count: " << count << endl;
       co_yield();
    }

    if (next)
    {
        queue.push(next);
    }
}

// named after order of start of execution
auto cor1 = bind(coroutine, 1, 42);
auto cor3 = bind(coroutine, 3, 43);
// these two add another coroutine (cor3) in it's body (next)
auto cor2 = bind(coroutine, 2, 44, cor3);
auto cor4 = bind(coroutine, 4, 45, cor3);

queue.push(cor1);
queue.push(cor2);

// simple "scheduler" for current thread, just a loop
// (should be in a separate thread, but for simplicity,
//  for the sake of this simple example, it is in the
/   thread as the main thread and before starting it,
//  some coroutines are already added (cor1 and cor2)
//  to make it all go round)
while (!finished)
{
    while (queue.empty() && !finished)
    {   
        co_yield();
    }

    if (!finished)
    {
        auto cor = queue.front();
        queue.pop();
        cor();
    }
}

IMHO этого недостаточно для полноценных волокон. Особенно если добавить какие-нибудь co_await (чтобы cor2 и cor4 зависели от выполнения cor3 при помощи co_await, а не просто закидывали их в queue).

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

я посмотрел по диагонали

Вот IMHO тут надо не по диагонали. И уж точно не вики. У нас, кстати, в институте препод был, который говорил, что если ему кто-нибудь википедию процитирует в работе или ответе, то сразу 2 поставит.

тебе там и стек разрисуют, что на нем хранится, и как переключается контекст покажут. чтобы его переключить надо спасти все регистры на текущий стек, и восстановить все регистры со стека той корутины, или треда, куда надо переключиться.

Это не отвечает на вопрос, что именно необходимо, чтобы превратить безстэковую корутину в волокно (fiber), кроме шедулера и возможности его выбрать, что можно легко дописать руками (псевдо-c++ и с захардкоженным «шедулером»):

queue<function<void(int, int)>> queue;

void coroutine(int id,
               int count,
               function<void(int,int)> next = function<void(int,int)>())
{
    while (count--)
    {
       cout << "id: " << id << ", count: " << count << endl;
       co_yield();
    }

    if (next)
    {
        queue.push(next);
    }
}

// named after order of start of execution
auto cor1 = bind(coroutine, 1, 42);
auto cor3 = bind(coroutine, 3, 43);
// this one adds another coroutine in it's body
auto cor2 = bind(coroutine, 2, 44, cor3);
auto cor4 = bind(coroutine, 4, 45, cor3);

queue.push(cor1);
queue.push(cor2);

// simple "scheduler" for current thread, just a loop
while (!finished)
{
    while (queue.empty() && !finished)
    {   
        co_yield();
    }

    if (!finished)
    {
        auto cor = queue.front();
        queue.pop();
        cor();
    }
}

IMHO этого недостаточно для полноценных волокон. Особенно если добавить какие-нибудь co_await (чтобы cor2 и cor4 зависели от выполнения cor3 при помощи co_await, а не просто закидывали их в queue).

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

я посмотрел по диагонали

Вот IMHO тут надо не по диагонали. И уж точно не вики. У нас, кстати, в институте препод был, который говорил, что если ему кто-нибудь википедию процитирует в работе или ответе, то сразу 2 поставит.

тебе там и стек разрисуют, что на нем хранится, и как переключается контекст покажут. чтобы его переключить надо спасти все регистры на текущий стек, и восстановить все регистры со стека той корутины, или треда, куда надо переключиться.

Это не отвечает на вопрос, что именно необходимо, чтобы превратить безстэковую корутину в волокно (fiber), кроме шедулера и возможности его выбрать, что можно легко дописать руками (псевдо-c++ и с захардкоженным «шедулером»):

queue<function<void(int, int)>> queue;

void coroutine(int id,
               int count,
               function<void(int,int)> next = function<void(int,int)>())
{
    while (count--)
    {
       cout << "id: " << id << ", count: " << count << endl;
       co_yield();
    }

    if (next)
    {
        queue.push(next);
    }
}

// named after order of start of execution
auto cor1 = bind(coroutine, 1, 42);
auto cor3 = bind(coroutine, 3, 43);
// this one adds another coroutine in it's body
auto cor2 = bind(coroutine, 2, 44, cor3);
auto cor4 = bind(coroutine, 4, 45, cor3);

queue.push(cor1);
queue.push(cor2);

// simple "scheduler" for current thread, just a loop
while (!finished)
{
    while (queue.empty())
        co_yield();
    auto cor = queue.front();
    queue.pop();
    cor();
}

IMHO этого недостаточно для полноценных волокон. Особенно если добавить какие-нибудь co_await (чтобы cor2 и cor4 зависели от выполнения cor3 при помощи co_await, а не просто закидывали их в queue).

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

я посмотрел по диагонали

Вот IMHO тут надо не по диагонали. И уж точно не вики. У нас, кстати, в институте препод был, который говорил, что если ему кто-нибудь википедию процитирует в работе или ответе, то сразу 2 поставит.

тебе там и стек разрисуют, что на нем хранится, и как переключается контекст покажут. чтобы его переключить надо спасти все регистры на текущий стек, и восстановить все регистры со стека той корутины, или треда, куда надо переключиться.

Это не отвечает на вопрос, что именно необходимо, чтобы превратить безстэковую корутину в волокно (fiber), кроме шедулера и возможности его выбрать, что можно легко дописать руками (псевдо-c++ и с захардкоженным «шедулером»):

queue<function<void(int, int)>> queue;

void coroutine(int id,
               int count,
               function<void(int,int)> next = function<void(int,int)>())
{
    while (count--)
    {
       cout << "id: " << id << ", count: " << count << endl;
       co_yield();
    }

    if (next)
    {
        queue.push(next);
    }
}

// named after order of start of execution
auto cor1 = bind(coroutine, 1, 42);
auto cor3 = bind(coroutine, 3, 44);
// this one adds another coroutine in it's body
auto cor2 = bind(coroutine, 2, 43, cor3);
auto cor4 = bind(coroutine, 4, 44, cor3);

queue.push(cor1);
queue.push(cor2);

// simple "scheduler" for current thread, just a loop
while (!finished)
{
    while (queue.empty())
        co_yield();
    auto cor = queue.front();
    queue.pop();
    cor();
}

IMHO этого недостаточно для полноценных волокон. Особенно если добавить какие-нибудь co_await (чтобы cor2 и cor4 зависели от выполнения cor3 при помощи co_await, а не просто закидывали их в queue).