if (_coro) | if (_coro) | ||||
{ | { | ||||
auto sch_ = this->current_scheduler(); | |||||
// auto sch_ = this->current_scheduler(); | |||||
auto sch_ = this_scheduler(); | |||||
/* | /* | ||||
if (sch_ == nullptr) | if (sch_ == nullptr) | ||||
sch_ = this_scheduler(); | sch_ = this_scheduler(); | ||||
*/ | */ | ||||
if (sch_) | |||||
sch_->push_task_internal(new awaitable_task_t<state_base>(this)); | |||||
sch_->push_task_internal(new awaitable_task_t<state_base>(this)); | |||||
} | } | ||||
} | } | ||||
if (_coro) | if (_coro) | ||||
{ | { | ||||
auto sch_ = this->current_scheduler(); | |||||
// auto sch_ = this->current_scheduler(); | |||||
auto sch_ = this_scheduler(); | |||||
/* | /* | ||||
if (sch_ == nullptr) | if (sch_ == nullptr) | ||||
sch_ = this_scheduler(); | sch_ = this_scheduler(); | ||||
*/ | */ | ||||
if (sch_) | |||||
sch_->push_task_internal(new awaitable_task_t<state_base>(this)); | |||||
sch_->push_task_internal(new awaitable_task_t<state_base>(this)); | |||||
} | } | ||||
} | } | ||||
void state_base::await_suspend(coroutine_handle<> resume_cb) | void state_base::await_suspend(coroutine_handle<> resume_cb) | ||||
{ | { | ||||
scoped_lock<lock_type> __guard(_mtx); | |||||
_coro = resume_cb; | _coro = resume_cb; | ||||
/* | |||||
if (_current_scheduler == nullptr) | if (_current_scheduler == nullptr) | ||||
{ | { | ||||
auto * promise_ = this->parent_promise(); | auto * promise_ = this->parent_promise(); | ||||
stptr->current_scheduler(_current_scheduler); | stptr->current_scheduler(_current_scheduler); | ||||
_depend_states.clear(); | _depend_states.clear(); | ||||
} | } | ||||
*/ | |||||
} | } | ||||
void state_base::current_scheduler(scheduler * sch_) | void state_base::current_scheduler(scheduler * sch_) | ||||
{ | { | ||||
/* | |||||
scoped_lock<lock_type> __guard(_mtx); | |||||
_current_scheduler = sch_; | _current_scheduler = sch_; | ||||
for (auto & stptr : _depend_states) | for (auto & stptr : _depend_states) | ||||
stptr->current_scheduler(sch_); | stptr->current_scheduler(sch_); | ||||
_depend_states.clear(); | _depend_states.clear(); | ||||
*/ | |||||
} | } | ||||
} | } |
std::cout << "OK" << std::endl; | std::cout << "OK" << std::endl; | ||||
_getch(); | _getch(); | ||||
} | } | ||||
//---------------------------------------------------------------------------------------------------------------------- | |||||
/* | |||||
const size_t POOL_COUNT = 8; | |||||
//这是一个重度计算任务,只能单开线程来避免主线程被阻塞 | |||||
auto async_heavy_computing_tasks(int64_t val) | |||||
{ | |||||
using namespace std::chrono; | |||||
awaitable_t<int64_t> awaitable; | |||||
std::thread([val, st = awaitable._state] | |||||
{ | |||||
std::this_thread::sleep_for(500ms); | |||||
st->set_value(val * val); | |||||
}).detach(); | |||||
return awaitable; | |||||
} | |||||
future_vt heavy_computing_sequential(int64_t val) | |||||
{ | |||||
for (size_t i = 0; i < 3; ++i) | |||||
{ | |||||
{ | |||||
scoped_lock<std::mutex> __lock(cout_mutex); | |||||
std::cout << val << " @" << std::this_thread::get_id() << std::endl; | |||||
} | |||||
val = co_await async_heavy_computing_tasks(val); | |||||
} | |||||
{ | |||||
scoped_lock<std::mutex> __lock(cout_mutex); | |||||
std::cout << val << " @" << std::this_thread::get_id() << std::endl; | |||||
} | |||||
} | |||||
void test_use_single_thread(int64_t val) | |||||
{ | |||||
//使用local_scheduler来申明一个绑定到本线程的调度器 my_scheduler | |||||
//后续在本线程运行的协程,通过this_scheduler()获得my_scheduler的地址 | |||||
//从而将这些协程的所有操作都绑定到my_scheduler里面去调度 | |||||
//实现一个协程始终绑定到一个线程的目的 | |||||
//在同一个线程里,申明多个local_scheduler会怎么样? | |||||
//----我也不知道 | |||||
//如果不申明my_scheduler,则this_scheduler()获得默认主调度器的地址 | |||||
local_scheduler my_scheduler; | |||||
{ | |||||
scoped_lock<std::mutex> __lock(cout_mutex); | |||||
std::cout << "running in thread @" << std::this_thread::get_id() << std::endl; | |||||
} | |||||
go heavy_computing_sequential(val); | |||||
this_scheduler()->run_until_notask(); | |||||
} | |||||
const size_t N = 2; | |||||
void test_use_multi_thread() | |||||
{ | |||||
std::thread th_array[N]; | |||||
for (size_t i = 0; i < N; ++i) | |||||
th_array[i] = std::thread(&test_use_single_thread, 4 + i); | |||||
test_use_single_thread(3); | |||||
for (auto & th : th_array) | |||||
th.join(); | |||||
} | |||||
void resumable_main_multi_thread() | |||||
{ | |||||
std::cout << "test_use_single_thread @" << std::this_thread::get_id() << std::endl << std::endl; | |||||
test_use_single_thread(2); | |||||
std::cout << std::endl; | |||||
std::cout << "test_use_multi_thread @" << std::this_thread::get_id() << std::endl << std::endl; | |||||
test_use_multi_thread(); | |||||
//运行主调度器里面的协程 | |||||
//但本范例不应该有协程存在,仅演示不要忽略了主调度器 | |||||
scheduler::g_scheduler.run_until_notask(); | |||||
} | |||||
void resumable_main_channel_mult_thread() | |||||
{ | |||||
} | |||||
*/ |
<FunctionLevelLinking>true</FunctionLevelLinking> | <FunctionLevelLinking>true</FunctionLevelLinking> | ||||
<IntrinsicFunctions>true</IntrinsicFunctions> | <IntrinsicFunctions>true</IntrinsicFunctions> | ||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> | <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||
<SDLCheck> | |||||
</SDLCheck> | |||||
<AdditionalIncludeDirectories>..\librf;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | <AdditionalIncludeDirectories>..\librf;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
<AdditionalOptions>/await </AdditionalOptions> | <AdditionalOptions>/await </AdditionalOptions> | ||||
<ExceptionHandling>Sync</ExceptionHandling> | <ExceptionHandling>Sync</ExceptionHandling> | ||||
<OmitFramePointers>true</OmitFramePointers> | <OmitFramePointers>true</OmitFramePointers> | ||||
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations> | <EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations> | ||||
<StringPooling>true</StringPooling> | <StringPooling>true</StringPooling> | ||||
<BufferSecurityCheck>false</BufferSecurityCheck> | |||||
<LanguageStandard>stdcpplatest</LanguageStandard> | <LanguageStandard>stdcpplatest</LanguageStandard> | ||||
<BufferSecurityCheck>false</BufferSecurityCheck> | |||||
</ClCompile> | </ClCompile> | ||||
<Link> | <Link> | ||||
<SubSystem>Console</SubSystem> | <SubSystem>Console</SubSystem> |