1.项目简介
协程(coroutine)不是进程或线程,其执行过程更类似于子例程,或者说不带返回值的函数调用。
一个程序可以包含多个协程,可以对比与一个进程包含多个线程。
我们知道多个线程相对独立,有自己的上下文,切换受系统控制。
而协程也相对独立,有自己的上下文,但是其切换由自己控制,当前协程切换到其他协程由当前协程来控制。
协程调度单位减小到函数,上下文切换不需要内核参与,不存在系统调用。
上下文切换开销降到最低,系统调用降到最低,没有锁竞争,没有信号处理。
保留了程序对请求的线性处理逻辑,提高了程序的开发效率,可扩展性和可维护性。协程是一种程序组件。
通常我们把协程理解为是一种程序自己实现调度、用于提高运行效率、降低开发复杂度的东西。
而State-Thread(以下简称st),就是一个由C语言编写的小巧、简洁却高效的开源协程库。
这个库基于单线程运作、不强制占用用户线程,给予了开发者最大程度的轻量级和较低的侵入性。
很多语言都拥有协程,例如python或者golang。
而对于c/c++而言,通常实现协程的常见方式,通常是依赖于glibc提供的setjump&longjump或者基于汇编语言,当然还有基于语义实现(protothread)。
linux上使用协程库的方式,通常也会分为替换函数和更为暴力的替换so来实现。当然而各种方式有各自的优劣。而st选用的汇编语言实现setjump&longjump和要求用户调用st_打头的函数来嵌入程序。
所以st具备了跨平台的能力,以及让开发者们更开心的“与允许调用者自行选择切换时机”的能力。
随着coroutine ts正式进入c++20,c++已经进入协程时代了。但是不幸的是c++20的协程标准只包含编译器需要实现的底层功能,并没有包含简单方便地使用协程的高级库,相关的类和函数进入std标准库估计要等到c++23。
本文先以协程库(State Threads)来讲解c++中的协程。
2.state-threads库下载与编译
https://sourceforge.net/projects/state-threads/
执行命令
make linux-debug
编译生成的可执行文件在/st/st-1.9/obj下
引用State-Threads库需要引用st.h头文件
该文件非源代码,乃编译生成
3.c++代码中引用State-Threads
#include <stdio.h>
#include <stdlib.h>
#include "st.h"
using namespace std;
void* do_calc(void* arg) {
int sleep_ms = (int)(long int)(char*)arg * 10;
int i = 0;
for (;;) {
i = i+1;
printf("in sthread #%d\n", i);
st_usleep(sleep_ms * 1000);
}
return NULL;
}
int main(int argc, char** argv) {
if (argc <= 1) {
printf("Test the concurrence of state-threads!\n"
"Usage: %s <sthread_count>\n"
"eg. %s 10000\n", argv[0], argv[0]);
return -1;
}
if (st_init() < 0) {
printf("error!");
return -1;
}
int i;
int count = atoi(argv[1]);
for (i = 1; i <= count; i++) {
if (st_thread_create(do_calc, NULL, 0, 0) == NULL) {
printf("error!");
return -1;
}
}
st_thread_exit(NULL);
return 0;
}
4.编译
g++ -I ./obj -g ./test.cpp ./obj/libst.a -o test
参考:
https://blog.csdn.net/win_lin/article/details/8242653