1. 程式人生 > >Linux高效能網路:協程系列05-協程實現之原語操作

Linux高效能網路:協程系列05-協程實現之原語操作

目錄

5.協程的實現之原語操作

  問題:協程的內部原語操作有哪些?分別如何實現的?


  協程的核心原語操作:create, resume, yield。協程的原語操作有create怎麼沒有exit?以NtyCo為例,協程一旦建立就不能有使用者自己銷燬,必須得以子過程執行結束,就會自動銷燬協程的上下文資料。以_exec執行入口函式返回而銷燬協程的上下文與相關資訊。co->func(co->arg) 是子過程,若使用者需要長久執行協程,就必須要在func函式裡面寫入迴圈等操作。所以NtyCo裡面沒有實現exit的原語操作。

create:建立一個協程

  1. 排程器是否存在,不存在也建立。排程器作為全域性的單例。將排程器的例項儲存線上程的私有空間pthread_setspecific。
  2. 分配一個coroutine的記憶體空間,分別設定coroutine的資料項,棧空間,棧大小,初始狀態,建立時間,子過程回撥函式,子過程的呼叫引數。
  3. 將新分配協程新增到就緒佇列 ready_queue中。

  實現程式碼如下:

int nty_coroutine_create(nty_coroutine **new_co, proc_coroutine func, void *arg) {

    assert(pthread_once(&sched_key_once, nty_coroutine_sched_key_creator) == 0);
    nty_schedule *sched = nty_coroutine_get_sched();

    if (sched == NULL) {
        nty_schedule_create(0);

        sched = nty_coroutine_get_sched();
        if (sched == NULL) {
            printf("Failed to create scheduler\n");
            return -1;
        }
    }

    nty_coroutine *co = calloc(1, sizeof(nty_coroutine));
    if (co == NULL) {
        printf("Failed to allocate memory for new coroutine\n");
        return -2;
    }

    //
    int ret = posix_memalign(&co->stack, getpagesize(), sched->stack_size);
    if (ret) {
        printf("Failed to allocate stack for new coroutine\n");
        free(co);
        return -3;
    }

    co->sched = sched;
    co->stack_size = sched->stack_size;
    co->status = BIT(NTY_COROUTINE_STATUS_NEW); //
    co->id = sched->spawned_coroutines ++;
co->func = func;

    co->fd = -1;
co->events = 0;

    co->arg = arg;
    co->birth = nty_coroutine_usec_now();
    *new_co = co;

    TAILQ_INSERT_TAIL(&co->sched->ready, co, ready_next);

    return 0;
}

yield:讓出CPU

void nty_coroutine_yield(nty_coroutine *co)

  引數:當前執行的協程例項
  呼叫後該函式不會立即返回,而是切換到最近執行resume的上下文。該函式返回是在執行resume的時候,會有排程器統一選擇resume的,然後再次呼叫yield的。resume與yield是兩個可逆過程的原子操作。

resume:恢復協程的執行權

int nty_coroutine_resume(nty_coroutine *co)

  引數:需要恢復執行的協程例項
  呼叫後該函式也不會立即返回,而是切換到執行協程例項的yield的位置。返回是在等協程相應事務處理完成後,主動yield會返回到resume的地方。

更多分享

email: [email protected]
email: [email protected]
email: [email protected]
協程技術交流群:829348971