You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何MacOS终端execlp调用ps时,ps不在自身列表显示?Linux却正常

问题:fork子进程执行ps -l在MacOS中无法找到自身PID的原因

我修改了一个基于fork()的C语言模板,让子进程执行ps -l命令,原本期望在ps输出列表中找到该子进程(验证其PID与执行ps前的子进程PID一致)。该代码在Ubuntu系统上运行完全正常,但在MacOS系统中,无法在输出里找到ps进程的条目。请问造成这种差异的原因是什么?

对应的C语言代码

#include <stdio.h>              /* Pour perror */
#include <stdlib.h>             /* Pour exit */
#include <unistd.h>             /* Pour fork, getpid, getppid, sleep */
#include <sys/types.h>          /* Pour pid_t (fork, getpid, getppid) */
#include <sys/wait.h>           /* Pour wait */

int main(void)
{
  pid_t ident;

  ident = fork();
  if (ident == -1)
  {
    perror("fork");
    return EXIT_FAILURE;
  }

  /* A partir de cette ligne, il y deux processus */
  printf("Cette ligne sera affichee deux fois\n");
  if (ident == 0)
  {
    /* Code execute uniquement par le fils */
    printf("Je suis le fils, PID: %d, père: %d\n", getpid(), getppid());
    execlp("ps", "ps", "-l", NULL);
  }
  else
  {
    /* Code execute uniquement par le pere */
    printf("Je suis le pere\n, PID: %d, père: %d\n", getpid(), getppid());
    wait(NULL);
  }

  return EXIT_SUCCESS;
}

原因分析

核心差异来自Linux与macOS平台ps工具的实现逻辑不同:

  • Ubuntu(Linux)的ps行为:当子进程通过execlp启动ps -l后,ps会遍历系统进程列表,此时自身进程已经完成初始化并被纳入系统进程表,因此输出中会包含该ps进程的条目(PID与原叉子进程一致,因为exec系列调用不会改变进程PID)。

  • MacOS的ps行为:macOS上的ps工具在生成进程快照时,会主动排除自身进程的记录。也就是说,ps在收集并输出进程信息时,不会把正在运行的自己加入到结果列表里,所以你看不到对应的PID条目。

验证方法

可以在子进程的execlp调用前加入sleep(1),然后再执行ps -l:

// 子进程代码中添加sleep
printf("Je suis le fils, PID: %d, père: %d\n", getpid(), getppid());
sleep(1); // 新增延迟
execlp("ps", "ps", "-l", NULL);

此时用top或活动监视器实时查看,能看到该ps进程存在,但ps -l的输出里依然找不到它,这就证明是ps工具的输出规则导致的,而非进程未创建。

另外注意代码中父进程的printf存在格式错误:"Je suis le pere\n, PID: ..."里的\n不应该放在逗号前,会导致输出换行混乱,但这与当前问题无关。

内容的提问来源于stack exchange,提问作者Nocta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 19:45:21