当前位置: 首页 > article >正文

C++ 协程

经典协程辅助入门代码:

typedef cotask::task my_task_t;

int main() {

// create a task using factory function [with lambda expression]

my_task_t::ptr_t task = my_task_t::create([]() { //创建协程

std::cout ()->get_id()

cotask::this_task::get_task()->yield();

std::cout ()->get_id()

// ! Make crash and it's will generate a mini dump into d:/libcopp-test-minidump-*.dmp

// copp::this_coroutine::get_coroutine()->yield();

return 0;

});

std::cout get_id()

// start a task

task->start();

std::cout get_id()

task->resume();

std::cout get_id()

return 0;

}

Task切换式:

/*

* sample_stress_test_task.cpp

*

* Created on: 2014年5月11日

* Author: owent

*

* Released under the MIT license

*/

#include

#include

#include

#include

#include

#include

#include

// include manager header file

#include

#define LIBCOTASK_MACRO_ENABLED

#ifdef LIBCOTASK_MACRO_ENABLED

# if defined(PROJECT_LIBCOPP_SAMPLE_HAS_CHRONO) && PROJECT_LIBCOPP_SAMPLE_HAS_CHRONO

# include

# define CALC_CLOCK_T std::chrono::system_clock::time_point

# define CALC_CLOCK_NOW() std::chrono::system_clock::now()

# define CALC_MS_CLOCK(x) static_cast(std::chrono::duration_cast(x).count())

# define CALC_NS_AVG_CLOCK(x, y) \

static_cast(std::chrono::duration_cast(x).count() / (y ? y : 1))

# else

# define CALC_CLOCK_T clock_t

# define CALC_CLOCK_NOW() clock()

# define CALC_MS_CLOCK(x) static_cast((x) / (CLOCKS_PER_SEC / 1000))

# define CALC_NS_AVG_CLOCK(x, y) (1000000LL * static_cast((x) / (CLOCKS_PER_SEC / 1000)) / (y ? y : 1))

# endif

typedef cotask::task<> my_task_t;

int switch_count = 100;

int max_task_number = 100000; // 协程Task数量

std::vector task_arr;

// define a coroutine runner

static int my_task_action(void *) {

// ... your code here ...

int count = switch_count; // 每个task地切换次数

cotask::impl::task_impl *self = cotask::this_task::get_task();

while (count-- > 0) {

self->yield();

}

return 0;

}

int main(int argc, char *argv[]) {

# ifdef LIBCOPP_MACRO_SYS_POSIX

puts("###################### context coroutine (stack using default allocator[mmap]) ###################");

# elif defined(LIBCOPP_MACRO_SYS_WIN)

puts("###################### context coroutine (stack using default allocator[VirtualAlloc]) ###################");

# else

puts("###################### context coroutine (stack using default allocator ###################");

# endif

printf("########## Cmd:");

for (int i = 0; i < argc; ++i) {

printf(" %s", argv[i]);

}

puts("");

if (argc > 1) {

max_task_number = atoi(argv[1]);

}

if (argc > 2) {

switch_count = atoi(argv[2]);

}

size_t stack_size = 16 * 1024;

if (argc > 3) {

stack_size = atoi(argv[3]) * 1024;

}

time_t begin_time = time(nullptr);

CALC_CLOCK_T begin_clock = CALC_CLOCK_NOW();

// create coroutines

task_arr.reserve(static_cast(max_task_number));

while (task_arr.size() < static_cast(max_task_number)) {

my_task_t::ptr_t new_task = my_task_t::create(my_task_action, stack_size);

if (!new_task) {

fprintf(stderr, "create coroutine task failed, real size is %d.\n", static_cast(task_arr.size()));

fprintf(stderr, "maybe sysconf [vm.max_map_count] extended.\n");

max_task_number = static_cast(task_arr.size());

break;

}

task_arr.push_back(new_task);

}

time_t end_time = time(nullptr);

CALC_CLOCK_T end_clock = CALC_CLOCK_NOW();

printf("create %d task, cost time: %d s, clock time: %d ms, avg: %lld ns\n", max_task_number,

static_cast(end_time - begin_time), CALC_MS_CLOCK(end_clock - begin_clock),

CALC_NS_AVG_CLOCK(end_clock - begin_clock, max_task_number));

begin_time = end_time;

begin_clock = end_clock;

// start a task

for (int i = 0; i < max_task_number; ++i) {

task_arr[i]->start();

}

// yield & resume from runner

bool continue_flag = true;

long long real_switch_times = static_cast(0);

while (continue_flag) {

continue_flag = false;

for (int i = 0; i < max_task_number; ++i) {

if (false == task_arr[i]->is_completed()) { //查询任务是否结束完成,采用while+for的方式进行多次检查,

continue_flag = true;

++real_switch_times;

task_arr[i]->resume();

}

}

}

end_time = time(nullptr);

end_clock = CALC_CLOCK_NOW();

printf("switch %d tasks %lld times, cost time: %d s, clock time: %d ms, avg: %lld ns\n", max_task_number,

real_switch_times, static_cast(end_time - begin_time), CALC_MS_CLOCK(end_clock - begin_clock),

CALC_NS_AVG_CLOCK(end_clock - begin_clock, real_switch_times));

begin_time = end_time;

begin_clock = end_clock;

task_arr.clear();

end_time = time(nullptr);

end_clock = CALC_CLOCK_NOW();

printf("remove %d tasks, cost time: %d s, clock time: %d ms, avg: %lld ns\n", max_task_number,

static_cast(end_time - begin_time), CALC_MS_CLOCK(end_clock - begin_clock),

CALC_NS_AVG_CLOCK(end_clock - begin_clock, max_task_number));

return 0;

}

#else

int main() {

puts("cotask disabled");

return 0;

}

#endif


http://www.kler.cn/a/146601.html

相关文章:

  • 【Linux】11.Linux基础开发工具使用(4)
  • 鸿蒙UI开发——键盘弹出避让模式设置
  • Linux之进程
  • C#,图论与图算法,任意一对节点之间最短距离的弗洛伊德·沃肖尔(Floyd Warshall)算法与源程序
  • mysql-5.7.18保姆级详细安装教程
  • vscode 扩展Cline、Continue的差别?
  • C++ 常见异常
  • 关于Java多线程的一些随笔
  • 一个简易计算器实现(c语言)
  • 自己动手实现一个深度学习算法——八、深度学习
  • 数据结构与算法编程题30
  • 多段图的最短路径【java】
  • 嵌入式硬件电路·电平
  • JVM 之 javac、java、javap 命令详解
  • 2、Mysql基准测试
  • ubuntu20.04配置OpenCV的C++环境
  • 3.前端--HTML标签-文本图像链接【2023.11.25】
  • docker环境日志常用命令
  • AI数字人与虚拟人:区别与应用场景
  • 【机器学习】聚类(二):原型聚类:LVQ聚类(学习向量量化)
  • 新材料制造ERP用哪个好?企业应当如何挑选适用的
  • 基于YOLOv5的视频计数 — 汽车计数实现
  • 论文阅读——MCAN(cvpr2019)
  • Python多线程使用(一)
  • S32K3之看门狗(autosar框架中的watchdog)
  • Redis链表使用