一、问题描述
编写一个程序,这个程序首先定义了一个整型变量var,并将这个变量初值赋值为0。然后创建一个子进程,父子进程各自循环10000次,每次循环里,父进程不断地对var加1,然后输出A[var的值]A,子进程不断地对var减1,然后输出a[var的值]a。编译并运行这个程序,记录你的运行结果,并予以解释。重新运行这个程序,并将这个结果重定向到result.txt文件中。查看result.txt,结果与显示在屏幕上一样吗?解释你所看到的现象。
二、问题解决
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int var = 0;
void child_process() {
for (int i = 0; i < 10000; i++) {
// 子进程每次循环减1
var--;
printf("a[%c]a\n", var);
usleep(1); // 短暂休眠以避免过快执行
}
}
int main() {
pid_t pid = fork();
if (pid < 0) {
// 出错处理
exit(1);
} else if (pid == 0) {
// 子进程
child_process();
exit(0);
} else {
// 父进程
for (int i = 0; i < 10000; i++) {
// 父进程每次循环加1
var++;
printf("A[%c]A\n", var);
usleep(1); // 短暂休眠以避免过快执行
}
wait(NULL); // 等待子进程结束
}
return 0;
}
三·、实验分析
由运行结果可知:每次运行的结果都不一致。这是因为该程序中的父进程和子进程都试图同时访问和修改同一个全局变量 var,但是没有使用任何同步机制来控制对它的访问。这就导致了竞态条件,即两个或多个进程在没有适当同步的情况下访问共享资源,从而导致了不可预测的结果。
重新运行这个程序,并将这个结果重定向到result.txt文件中,查看result.txt文件,发现在该文件中输出结果就会是连续的,即父进程和子进程对var修改后立即打印输出var的值,这与程序运行得到的貌似混乱的结果不一致。
运行结果与txt文件不一致的原因:当程序的运行结果被重定向到一个文本文件时,输出操作实际上是在写入文件系统。这些写入操作是由操作系统管理的,并且通常会被缓冲。这意味着数据可能首先被写入到操作系统为文件系统提供的缓冲区中,然后在适当的时机被刷新到磁盘上的文件。在没有显式同步机制的情况下,父进程和子进程可能会同时修改变量 var 并尝试输出其值。如果操作系统恰好在某个进程修改 var 并输出到文件之后、另一个进程修改 var 之前执行了缓冲区的刷新操作,那么在文本文件中看到的输出结果就会是连续的,给人一种每次修改 var 后立即输出的印象。