Linux进程管理从入门到实战:概念、状态、通信与排查 搞 Linux 服务器、写服务端程序或者哪怕只是在自己电脑上装了虚拟机跑 Linux进程这东西你迟早要正面撞上。很多人学 Linux 一开始背命令、配环境看着挺热闹一遇到“进程”就犯迷糊程序明明在跑ps 里也能看到可它就是不出窗口kill 杀了好几次进程还赖着不走程序崩了子进程没人管成了僵尸。这些问题听起来五花八门本质都是对进程的底层机制和生命周期没吃透。这篇文章是我长期折腾 Linux 的一点系统整理。从进程的基本概念、状态模型、父子关系到查看、调度、守护进程、进程间通信IPC最后落在一堆真实排查案例上。你不需要是内核专家也能看懂但看完之后处理类似问题心里会更有底。适合刚入门 Linux 的开发者、想系统补一下基础知识的运维以及准备面试时被“进程和线程区别”这类题问住的同学。1. 先把进程这个概念彻底吃透1.1 进程和程序到底差在哪一句话程序是躺在磁盘上的静态文件进程是运行起来的动态实体。你编译出来的那个二进制文件或者 Python 写的那个.py脚本在没有被操作系统加载执行之前不叫进程。只有当你敲下命令、系统把它装进内存、分配好资源、开始调度执行的那一刻它才成了进程。这个区别最直观的体现就是 PID。每个进程启动时操作系统会分配一个唯一编号叫进程号PID。同一个程序你启动十次会有十个不同的 PID因为它们是十个独立的进程实体。程序文件本身可能只有一份但运行中的实例可以有很多个。就像菜谱是那一本但照着菜谱做菜的厨师可能同时有十个人每个厨师炒出来的菜进程相互独立都有自己的锅和灶资源。搞懂这个区别你就明白为什么“进程占用内存”这件事很重要了。程序文件在磁盘上可能只有几 MB但多个进程启动后每个都有独立的内存空间内存开销会成倍放大。这也是为什么后来有了进程池、线程这类东西来控制资源消耗。1.2 进程与线程的关系别再被面试题唬住网上关于进程和线程的区别一搜一大把但很多都停留在“进程是资源分配的最小单位线程是 CPU 调度的最小单位”这种层面。这句话本身没错但光背下来没用得理解它背后的设计逻辑。进程是把程序运行所需的一切资源打包在一起独立的内存地址空间、打开的文件描述符、环境变量、信号处理器等等。而线程是在进程内部创建的执行流同一个进程里的多个线程共享这块内存空间和文件描述符只是各自有独立的栈和寄存器状态。所以线程切换确实比进程切换轻量因为不涉及地址空间的切换。但轻量是有代价的一个线程崩了可能导致整个进程跟着崩多个线程同时写同一个共享变量你需要加锁保护。我个人的体会是如果你要跑的任务本身就互不相干比如处理一批互相独立的订单数据用多进程更省心因为进程之间天然隔离一个挂了不影响其他如果任务是紧密协作、高频共享大量数据的比如一个 web 服务要处理并发请求多线程更合适因为共享内存的开销远小于 IPC。这里没有绝对的优劣只有合不合适。维度进程线程资源独立地址空间、独立文件描述符表共享进程地址空间隔离性强一个进程崩溃不影响其他进程弱线程崩溃可能导致整个进程退出通信需要管道、消息队列、共享内存等 IPC直接读写共享内存但要注意同步调度开销较大地址空间切换较小适用场景任务独立、需要强隔离任务紧密协作、数据共享频繁1.3 进程状态从创建到退出的一生在 Linux 里用ps aux看进程时STAT 列那一堆字母很多人扫一眼就过去了其实这些就是进程的“人生阶段”。老手看一眼状态列基本能判断出这进程现在卡在哪了。Linux 进程常见的状态有这几个状态码含义说明RRunning / Runnable正在运行或排在了运行队列里等着被调度SSleeping可中断在等待某个事件比如等 I/O 完成能被信号唤醒DSleeping不可中断通常是在等磁盘 I/O不能被普通信号打断TStopped被暂停了比如按了 CtrlZ或者收到了 SIGSTOPZZombie已退出但父进程没有回收它的退出状态XDead真正销毁了你看到它的机会非常短暂这里我想多说一下 D 状态。D 状态进程杀不掉因为它正在内核里做 I/O 操作比如等磁盘响应此时你发的 SIGKILL 信号会被暂时挂起直到内核觉得这个 I/O 操作可以安全中断。如果你发现一堆 D 状态进程优先怀疑存储系统出了问题磁盘故障、NFS 挂载失联、网络存储超时。我之前排查过一个 Cassandra 集群故障节点上大量进程陷入 D 状态最后发现是共享文件系统挂了恢复存储后进程才陆续醒来。1.4 一个容易忽略的概念进程的身份令牌写 Linux 程序的人迟早会遇到“权限”问题。你可能有疑问为什么普通用户执行sudo能临时拥有 root 权限执行完又变回普通用户了这里的关键是 Linux 给每个进程维护了不止一个 UID。真实用户 IDReal UID标识“这个进程属于哪个用户启动的”有效用户 IDEffective UID则决定“这个进程现在实际拥有谁的权利”。正常情况下两个值一样但当你运行一个设置了 setuid 位的程序时有效用户 ID 会被临时切换成文件属主的 ID。sudo的原理就是利用 setuid让普通用户启动的进程短暂获得 root 的有效身份执行完命令再退回去。这个机制在多人服务器上非常关键。你管理服务器时发现某进程“看着是普通用户启动的却好像能访问 root 文件”先别惊讶检查一下是不是可执行文件有 s 权限位ls -l的文件权限位里会出现 s。从防守角度看这就是为什么要注意检查系统中有没有可疑的 setuid 文件一旦被植入带 setuid 的二进制等于给别人留了提权通道。至于提权本身我不会在这里展开任何利用方法但作为运维你要随时检查系统的权限配置不给非授权者留下可乘之机。2. 进程查看与管理先会看才会管2.1 ps 命令不同场景下的几种常用组合ps大概是每个 Linux 用户第一个接触的进程命令但很多人就只会ps aux然后靠眼睛慢慢找。它确实是一个拼凑出来的习惯用写法a 显示所有终端进程u 展示用户名和 CPU/内存占用x 显示没有控制终端的进程。日常排查时这是最实用的组合。但如果进程特别多或者你想快速找某个进程盲目刷ps aux是浪费时间。我建议的组合有# 全格式看父进程 PID 和完整启动参数 ps -ef # 精确匹配进程名配合管道过滤 ps -ef | grep java # 只看你关心进程的 PID pgrep -f java.*order-service # 直接列出进程 PID 和名字方便脚本处理 ps -e -o pid,comm,args --sort-%mem | head -20有一个容易忽略的坑ps aux | grep 进程名会把grep自己那一条也匹配出来因为命令行的参数里确实包含你要查的关键字。虽然多一条也不致命但会对判断造成干扰。可以用pgrep替代或者用grep -v grep过滤再或者用pgrep -lf查看完整命令行比如ps aux | grep java | grep -v grep。2.2 动态监控与进程树ps是静态快照它只能告诉你“此刻”有哪些进程。真要排查 CPU 飙高、内存泄漏这种动态问题还得看实时动态监控。top是系统自带的老牌工具进去后按P按 CPU 排序按M按内存排序按1查看每个 CPU 核心的负载情况。这三个按键是入门基本功。htop是top的增强版支持上下键选择进程、F9 直接发信号、树形模式查看父子关系。多个 Linux 发行版默认没装用apt install htop或yum install htop补一下。我个人习惯用htop做交互排查用top -b -n 1做脚本监控因为-b批处理模式可以直接把结果输出到文件。进程树也很重要。你可能遇到过“某个应用起来后带了一堆子进程”的情况比如 Nginx 有一个 master 进程和多个 worker 进程。用pstree -p可以直观地看到谁是谁的孩子pstree -p 3210这会把 3210 号进程的子孙后代全部画出来。排查“某个子进程怎么还在跑”的时候非常有用能快速定位到它的父进程是谁顺藤摸瓜。2.3 如何精确查看进程和线程数量在这个热词满天飞的时代面试官爱问“怎么查看进程和线程数量”运维排查时也经常要看这个数字判断服务是不是异常了。先看整个系统一共有多少进程ps -e | wc -l但这里有坑ps -e输出的第一行是标题“PID TTY TIME CMD”所以实际进程数要减去 1。更准确的做法是用pgrep统计pgrep -c .想查整个系统的线程总数可以看/proc下的线程数总和但速度慢。简单点的办法是用ps -eLfps -eLf | wc -l这里每一行代表一个线程。比如一个进程开了 10 个线程ps -eLf里就会有 10 行记录着同样的 PID但 LWP轻量进程号不同。如果要查某个具体进程的线程数ps -T -p PID或者用top -H -p PID进去后按H切换到线程视图。还有一种更底层的方式是直接读/proc/PID/status里的Threads:字段我看到监控脚本里常用这个消耗很小grep Threads /proc/PID/status2.4 kill、killall 与信号的意义很多人在终端里敲kill -9敲得特别爽好像这是解决一切问题的银弹。实际上kill这个命令的核心不是“杀”而是“发信号”-9只是其中的一种信号而已。kill -l可以列出所有信号常见的有信号编号默认行为使用场景TERM15终止进程友好的退出请求程序可以捕获并清理KILL9无条件终止强制杀死进程无法捕获、无法忽略HUP1重新加载配置很多守护进程用它重读配置文件INT2中断等价于终端里 CtrlCSTOP19暂停相当于把进程挂起不占用 CPUCONT18继续配合 STOP让暂停的进程恢复知道信号的意义之后你就明白为什么不建议一上来就kill -9。比如 Nginx 和 SSH 这类服务对 TERM 信号会做优雅处理关闭监听端口、清理完当前连接再退出而如果你直接发 KILL它没机会清理临时文件和释放资源容易留下半残状态。生产环境中的通用做法是先kill PID发 TERM等几秒钟如果还活着再考虑kill -9 PID。另外kill是按 PID 发信号的killall是按进程名发信号。比如killall nginx会把所有叫 nginx 的进程都发一遍信号。但要注意killall在 Solaris 和 Linux 下的行为不完全一样跨平台脚本里建议先确认再使用。3. 父子进程、守护进程与生命周期管理3.1 fork 和 exec进程诞生的内幕很多人不知道Linux 里进程的创建其实分两步先fork再exec。fork会复制一份当前进程的内存映像生成一个几乎一模一样的子进程然后exec把子进程的内存替换成目标程序的镜像并开始执行。也就是说你运行/bin/ls时shell 先 fork 一份自己的副本再让这个副本 exec 成 ls 进程。理解这一点对排查父子关系特别有帮助。父进程 fork 出来的子进程会继承父进程的环境变量、打开的文件描述符、信号处理设置等但不会继承父进程持有的锁、定时器和未决的信号。孤儿进程指的是父进程先退出、子进程还在运行的进程。正常情况下孤儿进程会被 PID 为 1 的 init 或 systemd 进程收养避免它变成没人管的流浪汉。用一段简单的 C 代码可以直观感受 fork 的行为#include stdio.h #include unistd.h int main() { pid_t pid fork(); if (pid 0) { perror(fork failed); return 1; } else if (pid 0) { printf(I am child, pid%d, ppid%d\n, getpid(), getppid()); } else { printf(I am parent, pid%d, child%d\n, getpid(), pid); } return 0; }运行后你会发现父子进程都有各自的 PID而且fork()在父进程里返回子进程的 PID在子进程里返回 0。这个“返回值不同”的设计是区分父子进程的关键面试常考。3.2 僵尸进程是怎么来的如何处理僵尸进程绝对是 Linux 必考知识点。不是只有阴间才闹僵尸Linux 系统里也有。进程退出的时候不会立刻从进程表里消失它得先向父进程报告自己的退出状态等父进程调用wait()系统调用把这状态收走之后它才真正被清理掉。如果父进程一直没来收这个已经死了却还占着进程表条目的进程就成了僵尸进程Zombie。僵尸进程不占 CPU也不占内存但它占着 PID 和进程表项系统中大量僵尸进程会造成新的进程无法创建。我自己写测试程序时经常制造一批僵尸来观察#include stdio.h #include unistd.h #include sys/wait.h int main() { pid_t pid fork(); if (pid 0) { printf(child exiting now\n); _exit(0); } else { sleep(30); // 父进程不去 wait子进程就变僵尸 } return 0; }杀掉僵尸进程不是杀它本身因为僵尸已经死了。正确思路是杀掉它的父进程让僵尸进程被 init/systemd 收养由这种“孤儿院”统一回收。在容器环境里如果 PID 1 进程没有妥善处理这种信号容器里就可能堆积一批僵尸进程。写 Docker 镜像的时候很多人会用一个专门的 init 进程如 tini来启动主程序就是为了解决容器内僵尸进程回收问题。3.3 守护进程nohup、setsid 和 systemd守护进程是后台默默运行、不与终端交互的进程。你关掉终端后服务还在跑靠的就是它。常见的守护进程化方式有三种分别对应不同的使用深度。最早接触的是nohupnohup java -jar app.jar app.log 21 nohup的作用是让进程忽略 SIGHUP 信号终端断开时系统会给该终端的前台/后台进程发 SIGHUP然后配合放到后台。但这只能保证“关终端不退出”它还是当前终端的子进程如果 shell 会话被异常终止仍可能被连带清理。更彻底的方式是setsidsetsid ./start.shsetsid直接让进程脱离当前会话成为一个新的会话首进程彻底和终端断开关系比nohup 更干净。但最推荐的生产级做法是用 systemd 管理服务[Unit] DescriptionMy Awesome Service Afternetwork.target [Service] Userwww-data ExecStart/opt/myapp/bin/server start Restartalways RestartSec3 [Install] WantedBymulti-user.target把这段存到/etc/systemd/system/myapp.service然后执行systemctl daemon-reload systemctl enable --now myappsystemd 的优势不只是开机自启它还能在进程崩溃时自动拉起来Restartalways日志统一走 journald管理起多个副本的时候尤其方便。这就是一个基础版的“进程保护工具”。3.4 进程池是什么什么时候值得引入热词里出现了“进程池”这个概念在服务端开发里很常见。进程池的思路很简单与其频繁创建、销毁进程这个开销不小不如提前一次性创建一批固定的进程放在池子里循环利用。来一个任务就分配给池中空闲的进程处理处理完再还回去。举个 Golang 风格的例子package main import ( fmt sync ) func worker(id int, jobs -chan int, wg *sync.WaitGroup) { defer wg.Done() for job : range jobs { fmt.Printf(worker %d processing job %d\n, id, job) // 模拟处理耗时任务 } } func main() { const numWorkers 3 jobs : make(chan int, 10) var wg sync.WaitGroup for i : 1; i numWorkers; i { wg.Add(1) go worker(i, jobs, wg) } for j : 1; j 10; j { jobs - j } close(jobs) wg.Wait() }不管用的是 Go 的 goroutine、Python 的ProcessPoolExecutor还是自己维护一组进程核心目的都一样避免高频创建和销毁进程带来的系统调用开销提高吞吐。比如批量处理订单数据这种场景任务量很大但每个任务本身小用进程池比来一个任务起一个进程快得多。不过要注意池中的进程数量不是越大越好一般和 CPU 核数相当或者略高一点太多反而会因为上下文切换变慢。4. 进程通信IPC多进程协作的基础4.1 为什么要 IPC有哪些方式进程之间的隔离性是优点但也是麻烦想让两个进程配合工作比如 A 进程把数据交给 B 进程处理就得靠进程间通信。Linux 提供了一大堆 IPC 手段常见的包括管道、信号、消息队列、共享内存、信号量、Socket。它们各有各的适用场景没有谁能通吃一切。通信方式数据量性能典型应用管道小到中等中命令行过滤、父子进程传数据信号极小高通知事件、终止/暂停进程消息队列小到中等中服务端消息解耦共享内存大最高高频大数据量交换Socket任意中跨机器通信、本机跨语言通信我刚接触 IPC 时最大的困惑是为什么不能直接用一个全局变量因为进程有独立内存空间你改的是自己那份另一个进程根本看不见。IPC 的本质是在隔离的边界上搭一座桥把数据或者消息从一边送过去。4.2 管道命令行里每天都在用的 IPC管道是最简单也最常见的 IPC 方式。你在 shell 里写下cat log.txt | grep ERROR时已经用到了管道。|前面的命令把标准输出连接到一个管道后面的命令从管道读数据。内核负责在中间搬运不需要你手动写代码。如果要让两个独立进程之间用管道通信且它们之间没有父子关系就得用命名管道FIFO。创建方式mkfifo /tmp/my_fifo然后终端 A 往里写echo hello /tmp/my_fifo终端 B 读出来cat /tmp/my_fifo注意管道默认是阻塞的如果只有一端执行另一端没人读/写命令会卡在那里等对方接入。写脚本时记得配合timeout命令防止无限阻塞。命名管道很适合简单的一对一数据流但要做复杂一点的消息协议还是用消息队列或者 Socket 更合理。4.3 共享内存与消息队列的取舍共享内存的原理很好理解把同一块物理内存映射到多个进程的地址空间里进程可以直接读写这块共享区域。由于不需要内核在进程之间复制数据它是所有 IPC 方式里吞吐量最高的。典型接口是 POSIX 共享内存shm_open创建、mmap映射、shm_unlink释放。但共享内存光更快还不够它没有同步机制存在“多个进程同时写”的竞争问题。这时候需要配合信号量来做互斥。就用前面说到的信号量它像一个令牌只有拿到了令牌的进程才能写入共享内存写完释放令牌。消息队列则有点像一个中间人。进程往队列里发送消息对方从队列读取消息。消息是带类型的数据块读取方可以按类型选择读取天然支持异步解耦。SysV 消息队列的接口有三个msgget创建队列、msgsnd发送消息、msgrcv接收消息。用完记得清理不然用ipcs -q看到一堆残留队列万一业务异常崩了忘掉的队列会一直占用内核内存。清理命令是ipcrm -q msqid。我个人的选型经验是需要高吞吐、大数据量传输用共享内存最合适需要解耦、异步、可靠的消息传递用消息队列或真正的消息中间件只是简单的父子进程协作管道完全够用。4.4 信号最简单的轻量级通信很多人不知道信号本身就是一种 IPC 方式。进程收到一个信号等同于内核通知它“有事情发生了”——比如 CtrlC 发送的 SIGINT、kill命令发的 SIGTERM/SIGKILL以及进程运行出错时的 SIGSEGV 段错误。信号是异步的进程无法预期什么时候会收到什么信号只能提前设置好处理函数。写一个简单的 Python 示例捕获信号import signal import time import sys def handle_term(signum, frame): print(received TERM, cleaning up...) sys.exit(0) signal.signal(signal.SIGTERM, handle_term) while True: time.sleep(1)这个脚本收到kill PID发来的 TERM 信号后会执行清理逻辑再退出而不是猝死。这就是服务优雅停止的原理。反过来父进程还可以用 SIGCHLD 信号感知子进程退出从而及时调用wait()回收从设计上杜绝僵尸进程。5. 实战排查这些进程问题你会不会修5.1 ps 里有进程但界面或服务就是打不开这个现象在排查 GUI 应用时太常见了进程列表里明明能看到相关进程在运行可窗口死活不出来服务端口也连不上。很多人第一反应是“再启动一次”结果提示端口被占用于是更懵了它到底是在跑还是没在跑我遇到过一个典型场景某款 IM 客户端进程残留在后台界面因为某种原因挂了。因为进程还活着用户再点一次图标时程序检查到自己已有实例在运行就拒绝再启动直接退出或者抛错。这就形成了“进程在跑但没有窗口”的死锁。排这类的固定套路# 1. 先确认进程是谁占着的看完整命令行 ps -ef | grep 进程名 # 2. 确认它监听了什么端口 ss -tlnp | grep PID # 3. 看有没有锁文件残留 ls -l /tmp/*.lock /run/*.lock 2/dev/null # 4. 最后用 TERM 信号请它退出 kill PID锁文件是关键。很多应用为了防止多实例启动会写一个 PID 文件或者 socket 文件进程异常退出时文件没被删掉。它不是杀不掉进程而是这个“残留文件”骗过了应用自己的检查逻辑。处理办法很朴素确认没有正常的服务在运行之后把锁文件删掉再启动。但删之前一定要核实 PID 对应的进程是否真的死了别误删正在服务中的 PID 文件。5.2 进程杀不掉不同状态对应不同解法“kill 杀不掉进程”这种求助贴在网上长盛不衰。你仔细看其实分好几种情况每种解法完全不同。第一种进程处于 D 状态。前面说过这个状态是进程在内核态做不可中断的 I/O。此时kill -9信号发过去也会被搁置。你该看的是存储系统等 I/O 恢复进程通常会自己消失。如果 NFS 挂载失联了你还在等待进程可能真就永远卡在那里需要重启机器或者恢复存储。第二种进程被暂停了。如果在终端里按了 CtrlZ进程会进入 T 状态挂起不会继续执行。得用kill -CONT PID或者fg把它唤醒它才能继续跑。这种情况下你发 SIGTERM它也可能不予理睬必须先 CONTINUE 再 TERM。第三种僵尸进程。它其实已经死了只是没被父进程回收你没有办法用 kill 补刀。正确姿势是找到它的父进程让父进程退出或被重启把僵尸丢给 init/systemd 去收养。在容器环境里尽量让主进程承担子进程回收责任否则容器内僵尸很容易堆积到 PID 耗尽。第四种权限不足。普通用户想杀 root 起的进程系统会果断拒绝“Operation not permitted”。需要sudo kill但注意 sudo 之后也不要乱杀系统关键进程比如 PID 1 的 systemd一刀下去整个系统当场崩溃。5.3 常见问题速查表现象可能原因处理思路ps 里能看到进程但窗口不显示已有实例残留GUI 崩溃但进程没退出检查 PID 文件/锁文件确认无服务后 killkill -9 杀不掉D 状态不可中断 I/O或 T 状态暂停查存储/网络 I/O或先发 CONT 再 TERM端口显示被占用进程没死透或者本身就有监听进程ss -tlnp查看监听者确认后 kill后台进程跑了但看不到日志输出输出没有重定向到文件用nohup file 21 启动某个进程名不认识的占用 CPU 很高可能是服务子进程或可疑程序ps -ef看父进程和启动路径结合/proc/PID/exe判断内存不停涨内存泄漏或者缓存未释放top按内存排序定位进程再用pmap深入分析这里单独说一句“不认识但 CPU 占用很高”的进程先别急着定义成挖矿程序。有些框架启动的 worker 名显示得很奇怪但其实是正常组件。正确流程是先看启动命令、工作目录、可执行文件路径确认是不是你自己装的软件的子进程。像/proc/PID/exe可以查看进程实际指向的可执行文件/proc/PID/cwd看工作目录很多情况下能帮你快速判断这个进程从哪来、想干什么。如果确认是异常进程也不要直接 kill 了事先看它的父进程和启动方式找到它被拉起的原因不然杀掉之后可能又被拉起来。5.4 Linux 面试高频考点串讲既然热搜词里有 Linux 面试题我顺手把进程相关的常考内容串一遍。进程和线程的区别是选择题和简答题的常客。回答思路进程是资源分配的基本单位有独立内存空间创建开销大、隔离性好线程是 CPU 调度的基本单位共享进程内存创建开销小、隔离性差一个线程崩溃可能拖垮整个进程。fork 返回值也是个经典题。fork()调用一次返回两次父进程返回子进程 PID子进程返回 0返回负数则为创建失败。追问版还会问fork 之后父子进程谁先运行答案是“不确定”由内核调度器决定程序别依赖这个顺序。僵尸进程与孤儿进程的区别也常考。僵尸是子进程退出后父进程没有回收留下的残骸孤儿是父进程先退出子进程被 init 收养。协作问题通常还延伸出“如何在父进程中不阻塞等待子进程退出”这个问题答案就是 signal(SIGCHLD, handler) 处理子进程退出信号在 handler 里调用 waitpid。守护进程创建步骤如果面试官问得多可以从 fork、setsid、fork 再一次、chdir、umask、关闭文件描述符这套经典流程展开。生产环境里直接说用 systemd 管理更实际那套手动 daemonize 的流程了解原理即可。IPC 分类也常考管道、信号、共享内存、消息队列各说场景。进程通信这块我建议不要死背拿真实业务场景去套。比如你有两个服务需要传状态你会怎么选如果数据小且要求实时信号都能解决一部分需求如果要传文件内容管道或共享内存可以如果构建完整的事件系统那直接上消息队列或 MQ 中间件更省心。面试官最想看到的是你有“根据场景选方案”的能力而不是背 API 名单。我个人在工作里养成了一个习惯排查问题先看进程再往下挖。CPU 飙高先top定位进程内存泄漏先按内存排序服务挂不起先看 PID 和锁文件进程杀不掉先看状态码。搞清楚进程在那一层很多所谓的神秘问题其实都是基础概念没理顺。把进程的基础打牢后面学 cgroup、容器、Kubernetes 都会顺畅很多因为容器本质也是受限的进程集合调度器的核心对象照样是进程和线程。这些基础概念一通后面学什么都不慌。

相关新闻

最新新闻

C++对象的一生:从成员初始化列表到析构函数的完整生命周期

C++对象的一生:从成员初始化列表到析构函数的完整生命周期

这个标题其实是我在一次内部技术分享上随便起的,没想到大家对这个话题的反馈异常热烈。原因也简单:成员初始化列表看起来只是构造函数后面那一长串冒号写法,但把它讲透,牵出来的是C对象从无到有、从有到无的完整生命周期。很多人会…

2026/9/9 17:17:06
JMeter事务控制器实战:完整链路压测与报告分析

JMeter事务控制器实战:完整链路压测与报告分析

1. 一个再常见不过的场景:为什么单独看接口耗时,压测结果还是不对 前两天有个做后台开发的朋友拿了一份压测报告来找我,说他们的接口平均响应时间都在200毫秒以内,TPS也很高,可用户总反馈说操作很卡。我看了半天问了一…

2026/9/9 17:17:06
gitru:零依赖Rust实现的Git提交信息校验利器

gitru:零依赖Rust实现的Git提交信息校验利器

我第一眼看到 gitru 这个名字的时候,还以为是哪个拼写检查器把 repo 拼漏了,后来才反应过来是 git ru,Rust 的 ru。标题里那个“工具械”多半是手滑,按我的理解,它就是一个用 Rust 写的 Git 提交信息校验工具。这类工…

2026/9/9 17:17:06
真实AI Agent开发:217个Python进程的工程契约实践

真实AI Agent开发:217个Python进程的工程契约实践

1. 这不是科幻片,是SpaceX工程师日常写的Python脚本你刷到过那条被转疯的推文吗?一张截图里密密麻麻的终端窗口,每个窗口都挂着不同颜色的提示符,标题栏写着“Orion-Engine-Thrust-Controller”、“Starlink-Beam-Steering-Optimi…

2026/9/9 17:17:06
前端性能优化:从代码分割到懒加载,彻底解决首屏加载慢

前端性能优化:从代码分割到懒加载,彻底解决首屏加载慢

1. 首屏慢的真相:不是网速差,是资源太"胖"了 先说一个我印象特别深的场景。去年我给一个后台管理系统做性能体检,页面在办公室千兆局域网里加载,首屏居然要4秒多。打开DevTools一看,Network面板里密密麻麻全…

2026/9/9 17:17:06
发生即存在:意义行为原生论如何颠覆传统存在论

发生即存在:意义行为原生论如何颠覆传统存在论

哲学圈里有个老段子:一个人问另一个人“什么是存在?”,被问的人怔了一下,回答说——存在就是刚才你问出这个问题的那一瞬间,我自己也说不清、但它确确实实发生了的那件事。段子归段子,但细想之下&#xff0…

2026/9/9 17:12:06