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

子进程计数未达预期,是sleep()问题还是逐次输出计数的问题?

问题原因结论

你的两个猜想均正确,迭代次数不足是IO操作耗时和usleep最低时长保证两个因素共同作用的结果,还有少量额外因素也会放大误差。


具体原因说明

  • usleep的调度特性:POSIX标准明确规定usleep()的休眠时长是最小值,系统调度器只会保证进程不会在指定时长结束前被唤醒。如果休眠结束后CPU正被其他进程占用,子进程只能等待下一个调度时间片才能继续执行,单次循环的休眠耗时总会≥10ms,上千次循环累计后误差会非常可观。
  • printf的IO开销:标准输出默认是行缓冲模式,每次输出带\n的字符串都会触发缓冲区刷新,这个操作需要和内核交互,甚至要写入终端设备,单次开销在几微秒到几十微秒不等,累计下来会占用大量的预期运行时间。
  • 额外误差来源:父进程的sleep(10)同样遵循「至少休眠指定时长」的规则,实际唤醒时间可能略晚于10秒,加上kill发送信号到子进程响应终止也有微秒级延迟,也会小幅压缩子进程的有效运行窗口。

验证方法

你可以通过两个简单测试验证结论:

  1. 注释掉子进程中的printf语句后重新运行,iter最大值会明显升高,更接近1000的预期值
  2. 把usleep的参数调整为100000(即每次休眠100ms),你会发现迭代次数和预期的100次误差比例会显著降低,因为固定IO开销占单次循环总时长的比例大幅下降

代码笔误修正

你提供的代码存在一处笔误,父进程末尾的print("Everything has finished");应为printf("Everything has finished");,该问题不影响本次计数结果。修正后的参考代码如下(补充了必要的头文件):

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>

int main() {
    int iter=0, forkedProcess;
    forkedProcess = fork();
    if (forkedProcess == 0) {
        while (1) {
            iter++;
            printf("Count for process: child is %d\n", iter);
            /* sleep for 1/100 of a second */
            usleep(10000);
            }
     } 
     else {
         printf("Process sleeping for 10 seconds: Parent\n");
         sleep(10);
         kill(forkedProcess, SIGTERM);
         printf("Process killed: child. Waiting for it...\n");
         wait(NULL);
         printf("Everything has finished");
     }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 13:00:00