← SEARCHABLE ARCHIVE
Operating System · 2026-07-12

系统调用和上下文交换

用户程序如何向内核发出请求?

INTERACTIVE READING MODE →

该博客上撰写的文章是出于教学目的而创建的。 另外,文章中的信息可能不正确,请谨慎。

用户态程序不能直接控制磁盘或网络设备。 相反,它向操作系统请求工作,这种正式的请求方法称为系统调用。

它与常规函数调用有何不同?

一般函数调用仅更改同一权限区域内的执行位置。 对于系统调用,CPU权限从用户态转变为内核态,内核处理完请求后又返回用户态。

通用函数调用
用户代码→用户功能→用户代码

系统调用
用户代码→内核入口→权限和参数检查→内核操作→用户代码

打开文件、内存映射、套接字通信、进程创建等功能最终都会用到系统调用。 程序员通常会调用操作系统API或标准库,并在下面的层中执行相应的系统调用。

它与上下文切换不同

调用系统调用并不一定会改变到另一个进程。 同一个线程可能会进入内核模式,处理请求,然后立即返回。

上下文切换是通过保存当前执行状态并恢复另一个线程或进程的状态来改变执行目标的过程。

系统调用:同一个执行器向内核请求工作。
上下文切换:CPU改变主体本身来执行

然而,需要等待文件或网络数据的系统调用可以使当前线程处于等待状态。 与此同时,操作系统会运行其他线程以避免浪费CPU,此时可能会发生上下文切换。

系统调用不是免费的

权限切换和参数检查都是要花钱的。 这就是为什么在缓冲区中收集小数据并一次写入比一个字节写入数千次更有利的原因之一。

std::string buffer;

for (const auto& line : lines)
{
    buffer += line;
    buffer += '\n';
}

file.write(buffer.data(), buffer.size());

然而,这并不意味着应该不惜一切代价避免系统调用。 它是操作系统安全管理资源的必要边界,当发现性能问题时,最好查看调用和等待方法的数量。