首页 > 解决方案 > 如何检测c++的哪些代码导致模式切换

问题描述

我试图弄清楚哪些 c++ 代码会导致 Linux 上的模式切换(用户模式到内核模式)。我知道两件事:

  1. 系统调用导致模式切换:模式切换是否发生从用户线程切换到内核线程?
  2. 该命令strace可以列出所有系统调用。

现在我编写如下代码进行测试:

#include <iostream>
#include <chrono>
#include <thread>

int main()
{
    int i = 0;
    while (true) {
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        i++;
    }
    return 0;
}

我用命令编译它,g++ -std=c++11 test.cpp -lpthread然后运行strace -ttT ./a.out以列出它的系统调用。这是输出:

22:08:52.424382 prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0 <0.000009>
22:08:52.424611 brk(NULL)               = 0x55ca3968b000 <0.000009>
22:08:52.424725 brk(0x55ca396ac000)     = 0x55ca396ac000 <0.000011>
22:08:52.424887 futex(0x7f0aad83909c, FUTEX_WAKE_PRIVATE, 2147483647) = 0 <0.000010>
22:08:52.425070 futex(0x7f0aad8390a8, FUTEX_WAKE_PRIVATE, 2147483647) = 0 <0.000010>
22:08:52.425246 nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffcae110cb0) = 0 <1.000142>
22:08:53.425553 nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffcae110cb0) = 0 <1.000253>
22:08:54.425924 nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffcae110cb0) = 0 <1.000138>
22:08:55.426177 nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffcae110cb0) = 0 <1.000145>
22:08:56.426455 nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffcae110cb0) = 0 <1.000141>
22:08:57.426710 nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffcae110cb0) = 0 <1.000146>
22:08:58.426967 nanosleep({tv_sec=1, tv_nsec=0}, 0x7ffcae110cb0) = 0 <1.000146>

现在我有一些问题:

  1. 为什么会有futex?据我所知,futex在 c++11 中实现线程互斥锁的较低机制是什么,但我在这里没有使用任何互斥锁,为什么会有futex呢?
  2. 我们可以看到有infinite nanosleep,那么这是否意味着c++11代码std::this_thread::sleep_for(std::chrono::milliseconds(1000));会导致模式从用户模式切换到内核模式呢?
  3. 有没有更好的方法来检查哪些 c++ 代码/函数会导致模式切换或者我必须使用命令strace

标签: c++c++11context-switchkernel-mode

解决方案


推荐阅读