【学习笔记】关于一道fork()之后printf()输出的题目

本文通过解析printf函数的行为和fork系统调用的过程,揭示了一个看似简单的C程序背后隐藏的复杂执行逻辑,解释了为何程序输出的字符数量与直观理解存在差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在某网站线上答题中遇到一题目描述如下:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 以下程序输出的‘-’的个数为()  
  2. A.6    B.8    CD略  
  3.   
  4. #include <stdio.h>  
  5. #include <stdlib.h>  
  6. int main(void)  
  7. {  
  8.     int i;  
  9.     for(i = 0;i<2; i++)  
  10.     {  
  11.         fork();  
  12.         printf("-");  
  13.     }  
  14.   
  15.     return 0;  
  16. }  

简单算了下是6个,结果发现答案是8。非常纳闷,就和实验室的讨论了下,并写了几个测试。


测试用例一

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. int main(void)  
  4. {  
  5.     int i;  
  6.     for(i = 0;i<2; i++)  
  7.     {  
  8.         fork();  
  9.         printf("-\n");  
  10.     }  
  11.   
  12.     return 0;  
  13. }  

该程序输出了6个‘-’,并分为六行


测试用例二

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. int main(void)  
  4. {  
  5.     printf("-");  
  6.     sleep(1);  
  7.     return 0;  
  8. }  

该程序在阻塞1秒后,输出‘-’


由此,得到结论:

1.printf()函数并非是将数据直接直接发送到屏幕上,而是将其暂存到缓存区。

2.缓存区的内容不会立即发送到屏幕上,而是等待当出现‘\n’,EOF,缓存区满,或是进程结束时,再将缓存区中所有的内容发送到屏幕上。


所以我们在回到刚才的题上,其实这个问题的重点在printf()函数上,而不是fork()!

第一次循环,fork()生成两个进程,并在每个进程的缓冲区内写入一个‘-’。注意,此时的printf();之后,内容是不输出到屏幕上的。

第二次循环,fork()再次生成两个新进程,并在每个进程的缓冲区再写入一个‘-’。此时共有四个进程,每个进程的缓冲区内存放两个‘-’。

结束循环,进程读取到return,将缓冲区内的信息输出到屏幕,并清空缓冲区。


这就解释了为什么会出现8个‘-’的现象。

### 关于操作系统导论的相关作业资料 对于《操作系统导论》一书中的相关内容以及其配套的练习题和解答,可以通过多种途径获取。以下是关于该主题的一些具体说明: #### 1. **过程管理** 在《操作系统导论》第五章“Process API”的课后习题中提到的内容涉及进程创建、终止、同步等问题[^1]。这些题目通常围绕以下几个方面展开: - 进程的状态转换及其生命周期。 - 使用系统调用(如 `fork()` 和 `exec()`)来实现多进程编程。 以下是一个简单的 C 语言代码示例,用于演示如何通过 `fork()` 创建子进程并执行不同的任务: ```c #include <stdio.h> #include <unistd.h> int main() { pid_t pid = fork(); if (pid == 0) { // 子进程 printf("Child process running with PID %d\n", getpid()); } else if (pid > 0) { // 父进程 printf("Parent process created child with PID %d\n", pid); } else { // 错误处理 perror("Fork failed"); } return 0; } ``` #### 2. **资源管理** 从资源管理的角度来看,操作系统主要负责四种核心资源的分配与调度[^2]。这四个类别分别是: - 处理器(CPU) - 内存(RAM) - 输入/输出设备(I/O Devices) - 文件系统(File Systems) 这种分类有助于理解操作系统的整体架构设计原则,并指导开发者优化程序性能。 #### 3. **磁盘访问机制** 当涉及到移动存储介质的数据读写时,《计算机操作系统导论作业.pdf》提及了一种特定场景下的技术细节[^3]。虽然原文表述较为模糊,但可以推测它讨论的是随机访问模式下提高效率的方法之一——预取策略或者缓存算法的应用实例。 --- ### 提供的操作系统学习材料建议 如果希望获得更多类似的练习机会,则可以从以下几个方向入手查找合适的学习资源: - 官方教材附带光盘或在线补充文档; - 教育网站上公开分享的教学案例集锦; - 同学间相互交流整理出来的笔记汇总文件; 注意甄别来源可靠性的同时也要尊重版权规定!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值