经典协程辅助入门代码:
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