gpt4 book ai didi

c++ - 在 Windows 上使用 WaitForSingleObject 但支持 boost 线程中断

转载 作者:可可西里 更新时间:2023-11-01 11:52:27 28 4
gpt4 key购买 nike

Boost 线程具有“可中断”的便利特性。该框架在您 sleep 等时引入了中断点。但是,使用阻塞 Win32 调用可以规避此功能。例如,WaitForSingleObject会阻塞一个线程,但不会让它被boost线程的中断机制打断。

有什么方法可以包装 WaitForSingleObject 或告诉 boost 等待 Win32 事件句柄,以便我可以重新获得中断点?

最佳答案

detail::win32::interruptible_wait 实现了这一点。

如您所见,它等待 3 个句柄(除了调用者指定的句柄之外还有 2 个)以接受中断。

具体看

  • WaitForMultipleObjectsEx 调用
  • block

    else if(notified_index==interruption_index)
    {
    detail::win32::ResetEvent(detail::get_current_thread_data()->interruption_handle);
    throw thread_interrupted();
    }

供引用,Boost License :

bool interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time)
{
detail::win32::handle handles[3]={0};
unsigned handle_count=0;
unsigned wait_handle_index=~0U;
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
unsigned interruption_index=~0U;
#endif
unsigned timeout_index=~0U;
if(handle_to_wait_for!=detail::win32::invalid_handle_value)
{
wait_handle_index=handle_count;
handles[handle_count++]=handle_to_wait_for;
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
if(detail::get_current_thread_data() && detail::get_current_thread_data()->interruption_enabled)
{
interruption_index=handle_count;
handles[handle_count++]=detail::get_current_thread_data()->interruption_handle;
}
#endif
detail::win32::handle_manager timer_handle;

#ifndef UNDER_CE
#if !BOOST_PLAT_WINDOWS_RUNTIME
unsigned const min_timer_wait_period=20;

if(!target_time.is_sentinel())
{
detail::timeout::remaining_time const time_left=target_time.remaining_milliseconds();
if(time_left.milliseconds > min_timer_wait_period)
{
// for a long-enough timeout, use a waitable timer (which tracks clock changes)
timer_handle=CreateWaitableTimer(NULL,false,NULL);
if(timer_handle!=0)
{
LARGE_INTEGER due_time=get_due_time(target_time);

bool const set_time_succeeded=SetWaitableTimer(timer_handle,&due_time,0,0,0,false)!=0;
if(set_time_succeeded)
{
timeout_index=handle_count;
handles[handle_count++]=timer_handle;
}
}
}
else if(!target_time.relative)
{
// convert short absolute-time timeouts into relative ones, so we don't race against clock changes
target_time=detail::timeout(time_left.milliseconds);
}
}
#endif
#endif

bool const using_timer=timeout_index!=~0u;
detail::timeout::remaining_time time_left(0);

do
{
if(!using_timer)
{
time_left=target_time.remaining_milliseconds();
}

if(handle_count)
{
unsigned long const notified_index=detail::win32::WaitForMultipleObjectsEx(handle_count,handles,false,using_timer?INFINITE:time_left.milliseconds, 0);
if(notified_index<handle_count)
{
if(notified_index==wait_handle_index)
{
return true;
}
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
else if(notified_index==interruption_index)
{
detail::win32::ResetEvent(detail::get_current_thread_data()->interruption_handle);
throw thread_interrupted();
}
#endif
else if(notified_index==timeout_index)
{
return false;
}
}
}
else
{
detail::win32::sleep(time_left.milliseconds);
}
if(target_time.relative)
{
target_time.milliseconds-=detail::timeout::max_non_infinite_wait;
}
}
while(time_left.more);
return false;
}

关于c++ - 在 Windows 上使用 WaitForSingleObject 但支持 boost 线程中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27026570/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com