協程可以很方便在乙個執行緒中實現多個函式間的切換執行,如果某個函式需要等待,則可以切換到其他函式,這可以很大程度提高乙個執行緒的利用率,因此現在很流行;c++很多版本原生並沒有提供協程,但是由於c++支援內聯彙編,所以實現一套協程api並非難事,只要實現函式間的上下文切換,其他的就容易多了,上下文切換通常就是儲存當前函式的暫存器,由於是主動切換所以需要儲存的暫存器也就很少了,下面給出一種協程的實現方式:
coroutine.h
#ifndef m_coroutine_h
#define m_coroutine_h
//coroutine info
typedef struct
mcoroutine;
mcoroutine* alloc_co();
mcoroutine* pop_co();
bool createcoroutine(void (*task)(void*), void* args);
void schedule();
void runtask();
#define co_yield schedule();
#define print(str,...) printf(str##"\n",__va_args__)
#endif
coroutine.cpp
#include #include #include #include "coroutine.h"
//define the size of the coroutine stack
#define coroutine_stack_size 1024*1024*1 // 1m stack
#define max_coroutine 1000 // max coroutine num
//coroutine status flag
enum flags ;
std::listglobalcoroutinelist; // global coroutine list
static int coroutinerunningcount = 0; // the running count of coroutine
static mcoroutine cor_main = ; //main thread coroutine
static mcoroutine *currentcoroutine = &cor_main; //the current running coroutine
//assign a coroutine
mcoroutine *alloc_co()
auto *co = new mcoroutine();
globalcoroutinelist.push_back(co);
return co;
} globalcoroutinelist.push_back(co);
}// pop a coroutine from global coroutine list
mcoroutine *pop_co()
mcoroutine *co;
co = globalcoroutinelist.front();
globalcoroutinelist.pop_front();
return co;
}//this function will be run for the first time, and the task will be called by this function
static void coroutine_startup(mcoroutine *coroutine)
static void push_stack(unsigned int **stack_top_p_p, unsigned int val)
static bool init_stack(mcoroutine *coroutine)
static unsigned int id_num = 1;
static unsigned int get_id()
bool createcoroutine(void (*task)(void *), void *args)
void __fastcall release_coroutine(mcoroutine *coroutine)
__declspec(naked) void switch_context(mcoroutine *cur_coroutine, mcoroutine *dst_coroutine)
}void schedule()
switch(currentcoroutine->flag)
src_coroutine = currentcoroutine;
currentcoroutine = dst_coroutine;
switch_context(src_coroutine, dst_coroutine);
//print("switch_context over: src_coroutine:%d,dst_coroutine:%d", src_coroutine->id, dst_coroutine->id);
}void runtask() while (coroutinerunningcount);
}
main.cpp
#include "coroutine.h"
#include void task(void* num)
}int main()
runtask();
return 0;
}
cmakelists.txt
cmake_minimum_required(version 3.16)
project(mythread)
set(cmake_cxx_standard 14)
add_executable(test00 main.cpp coroutine.cpp coroutine.h)
執行結果:
start...
coroutine0 start...
coroutine0_0
coroutine1 start...
coroutine1_0
coroutine2 start...
coroutine2_0
coroutine3 start...
coroutine3_0
coroutine4 start...
coroutine4_0
coroutine5 start...
coroutine5_0
coroutine6 start...
coroutine6_0
coroutine7 start...
coroutine7_0
coroutine8 start...
coroutine8_0
coroutine9 start...
coroutine9_0
coroutine0_1
coroutine1_1
coroutine2_1
C C 協程的實現方式總結
1 利用 c 語言的 setjmp 和 longjmp,函式中使用 static local 的變數來儲存協程內部的資料。函式原型 int setjmp jmp buf envbuf void longjmp jmp buf envbuf,int val 先呼叫setjmp,用變數envbuf記錄當...
一種協程的 C C 實現
在前幾天接觸到了協程的概念,覺得很有趣。因為我可以使用乙個執行緒來實現乙個類似多執行緒的程式,如果使用協程來替代執行緒,就可以省去很多原子操作和記憶體柵欄的麻煩,大大減少與執行緒同步相關的系統呼叫。因為我只有乙個執行緒,而且協程之間的切換是可以由函式自己決定的。我有見過幾種協程的實現,因為沒有 c ...
gevent實現協程
1 yield實現 import time def task 1 while true print 1 time.sleep 0.1 yield def task 2 while true print 2 time.sleep 0.1 yield def main t1 task 1 建立迭代器 t...