Linux线程调度bug,单进程中不公平的linux线程调度

我有一个有两个线程的进程 .

第一个线程正在执行异步工作 - 它在 epoll_wait 中等待描述符和计时器事件上的IO .

第二个线程正在进行大量的IO /内存工作 - 它从磁盘读取数据,在内存中处理它,分配大量新内存,将其写入磁盘等等 .

问题是 epoll_wait 中的第一个线程阻塞的时间要长得多,然后在 epoll_wait 的超时时间内被请求(例如,超时被指定为1500毫秒,实际上是在10秒内从 epoll_wait 返回) .

这种行为我可以在虚拟机中可靠地重现(VirtualBox with Ubuntu 16.04) .

来自 GDB 的行为示例:

Thread 2.1 "se.real" hit Breakpoint 1, boost::asio::detail::epoll_reactor::run (this=0x826ebe0, block=true, ops=...) at /opt/com/include/boost/158/boost/asio/detail/impl/epoll_reactor.ipp:392

392 in /opt/com/include/boost/158/boost/asio/detail/impl/epoll_reactor.ipp

16:36:38.986826839

$17 = 1945

Thread 2.1 "se.real" hit Catchpoint 3 (call to syscall epoll_wait), 0xf7fd8be9 in __kernel_vsyscall ()

16:36:38.992081396

Thread 2.1 "se.real" hit Catchpoint 3 (returned from syscall epoll_wait), 0xf7fd8be9 in __kernel_vsyscall ()

16:36:54.681444938

断点1设置为 call epoll_wait 之前的指令,打印参数为超时参数值(1945 ms) .

打印时间是 shell date +"%T.%N" 命令的时间 .

Catchpoint 3是 epoll_wait 系统调用的系统调用捕获点(第一个用于输入,第二个用于返回) .

我们可以很容易地看到我们在内核中花了大约16秒,当时请求了1945毫秒 .

我从另一个复制品中收集了 perf record 事件 . 而且我完全看到:

se.real 4277 [001] 113049.144027: sched:sched_switch: prev_comm=se.real prev_pid=4277 prev_prio=120 prev_state=t|K ==> next_comm=strace next_pid=4142 next_prio=120

se.real 4277 [001] 113056.407952: sched:sched_stat_runtime: comm=se.real pid=4277 runtime=153767 [ns] vruntime=409222246640 [ns]

线程4277(具有异步IO和 epoll_wait 的第一个线程)没有任何其他sched事件约7秒 . 与此同时,这些事件之间有大量的计划活动 . 此活动包括第二个线程(具有大量IO /内存工作的线程), swapper / kswapd 以及其他用户空间进程 .

问题是我能做些什么才能有机会运行第一个线程?

Update: 将调度策略更改为 SCHED_FIFO for process doesn't solve problem - I' m仍然可以稳定地重现该问题 .

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值