linux非阻塞等待线程,linux – 即使异步I / O操作挂起,只有线程处理io_service正在等待...
這是一個(gè)錯(cuò)誤.我已經(jīng)能夠通過在task_io_service :: do_poll_one的非關(guān)鍵部分添加延遲來復(fù)制它.以下是
booost/asio/detail/impl/task_io_service.ipp中修改后的task_io_service :: do_poll_one()的片段.添加的唯一行是sleep.
std::size_t task_io_service::do_poll_one(mutex::scoped_lock& lock,task_io_service::thread_info& this_thread,const boost::system::error_code& ec)
{
if (stopped_)
return 0;
operation* o = op_queue_.front();
if (o == &task_operation_)
{
op_queue_.pop();
lock.unlock();
{
task_cleanup c = { this,&lock,&this_thread };
(void)c;
// Run the task. May throw an exception. Only block if the operation
// queue is empty and we're not polling,otherwise we want to return
// as soon as possible.
task_->run(false,this_thread.private_op_queue);
boost::this_thread::sleep_for(boost::chrono::seconds(3));
}
o = op_queue_.front();
if (o == &task_operation_)
return 0;
}
...
我的測(cè)試驅(qū)動(dòng)程序非常基礎(chǔ):
>通過計(jì)時(shí)器進(jìn)行異步工作循環(huán),打印“.”每3秒鐘一次.
>生成一個(gè)將輪詢io_service的線程.
>延遲允許新線程時(shí)間輪詢io_service,并且當(dāng)poll線程在task_io_service :: do_poll_one()中休眠時(shí),主調(diào)用io_service :: run().
測(cè)試代碼:
#include
#include
#include
#include
#include
boost::asio::io_service io_service;
boost::asio::steady_timer timer(io_service);
void arm_timer()
{
std::cout << ".";
std::cout.flush();
timer.expires_from_now(boost::chrono::seconds(3));
timer.async_wait(boost::bind(&arm_timer));
}
int main()
{
// Add asynchronous work loop.
arm_timer();
// Spawn poll thread.
boost::thread poll_thread(
boost::bind(&boost::asio::io_service::poll,boost::ref(io_service)));
// Give time for poll thread service reactor.
boost::this_thread::sleep_for(boost::chrono::seconds(1));
io_service.run();
}
調(diào)試:
[twsansbury@localhost bug]$gdb a.out
...
(gdb) r
Starting program: /home/twsansbury/dev/bug/a.out
[Thread debugging using libthread_db enabled]
.[New Thread 0xb7feeb90 (LWP 31892)]
[Thread 0xb7feeb90 (LWP 31892) exited]
此時(shí),arm_timer()已打印“.”曾經(jīng)(當(dāng)它被武裝起來時(shí)). poll線程以非阻塞方式為反應(yīng)器提供服務(wù),并且在op_queue_為空時(shí)睡眠3秒(當(dāng)task_cleanup c退出范圍時(shí),task_operation_將被添加回op_queue_).當(dāng)op_queue_為空時(shí),主線程調(diào)用io_service :: run(),看到op_queue_為空,并使自己成為first_idle_thread_,它在wakeup_event上等待. poll線程完成休眠,并返回0,主線程等待wakeup_event.
等待10秒后,arm_timer()有足夠的時(shí)間準(zhǔn)備就緒,我打斷調(diào)試器:
Program received signal SIGINT,Interrupt.
0x00919402 in __kernel_vsyscall ()
(gdb) bt
#0 0x00919402 in __kernel_vsyscall ()
#1 0x0081bbc5 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0
#2 0x00763b3d in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libc.so.6
#3 0x08059dc2 in void boost::asio::detail::posix_event::wait >(boost::asio::detail::scoped_lock&) ()
#4 0x0805a009 in boost::asio::detail::task_io_service::do_run_one(boost::asio::detail::scoped_lock&,boost::asio::detail::task_io_service_thread_info&,boost::system::error_code const&) ()
#5 0x0805a11c in boost::asio::detail::task_io_service::run(boost::system::error_code&) ()
#6 0x0805a1e2 in boost::asio::io_service::run() ()
#7 0x0804db78 in main ()
并排時(shí)間表如下:
poll thread | main thread
---------------------------------------+---------------------------------------
lock() |
do_poll_one() |
|-- pop task_operation_ from |
| queue_op_ |
|-- unlock() | lock()
|-- create task_cleanup | do_run_one()
|-- service reactor (non-block) | `-- queue_op_ is empty
|-- ~task_cleanup() | |-- set thread as idle
| |-- lock() | `-- unlock()
| `-- queue_op_.push( |
| task_operation_) |
`-- task_operation_ is |
queue_op_.front() |
`-- return 0 | // still waiting on wakeup_event
unlock() |
盡我所知,修補(bǔ)沒有副作用:
if (o == &task_operation_)
return 0;
至:
if (o == &task_operation_)
{
if (!one_thread_)
wake_one_thread_and_unlock(lock);
return 0;
}
無論如何,我已經(jīng)提交了bug and fix.考慮留意官方回復(fù)的機(jī)票.
總結(jié)
以上是生活随笔為你收集整理的linux非阻塞等待线程,linux – 即使异步I / O操作挂起,只有线程处理io_service正在等待...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何用oracle查看内存使用情况,or
- 下一篇: python教程程序_Python如何发