当前位置: 技术问答>linux和unix
linux C语言中有关'\n'的疑惑!
来源: 互联网 发布时间:2016-10-06
本文导语: 进程的创建: 题目:编写一个程序,输入两个整数并求和输出,然后创建一个子进程,当进程调度程序调度到父进程或子进程时特输出不同的信息。(父进程输出:I am father process! My Id=进程号; 子进程输出:I am son p...
进程的创建:
题目:编写一个程序,输入两个整数并求和输出,然后创建一个子进程,当进程调度程序调度到父进程或子进程时特输出不同的信息。(父进程输出:I am father process! My Id=进程号; 子进程输出:I am son process ! my id=***)
代码如下:
(1)
//test1.c
#include
int main()
{
int m = 5 , n = 15;
int pid_t;
printf("The Sum of m and n is:%dn",m + n); pid_t = fork();
if(pid_t == 0)
{
printf("I am son process ! My process id = %dn",getpid());
}
else
{
printf("I am father process ! My id = %dn",getpid());
}
return 0;
}
编译程序test1.c并运行后得到运行结果:
[u2342010345@localhost u2342010345]$ gcc -o test1 test1.c
[u2342010345@localhost u2342010345]$ ./test1
The Sum of m and n is:20
I am son process ! My process id = 4223
I am father process ! My id = 4222
我的问题是,为什么我将红体字部分改为printf("The Sum of m and n is:%d",m + n);
即将printf函数当中的'n'去掉之后为什么改语句执行了两次?
即运行结果为:
[u2342010345@localhost u2342010345]$ gcc -o test1 test1.c
[u2342010345@localhost u2342010345]$ ./test1
The Sum of m and n is:20I am son process ! My process id = 4554
The Sum of m and n is:20I am father process ! My id = 4553
确实不是很明白为什么会出现这样奇怪的结果,按道理
用fork函数创建子进程时,之前的语句不会再子进程中存在的。
题目:编写一个程序,输入两个整数并求和输出,然后创建一个子进程,当进程调度程序调度到父进程或子进程时特输出不同的信息。(父进程输出:I am father process! My Id=进程号; 子进程输出:I am son process ! my id=***)
代码如下:
(1)
//test1.c
#include
int main()
{
int m = 5 , n = 15;
int pid_t;
printf("The Sum of m and n is:%dn",m + n); pid_t = fork();
if(pid_t == 0)
{
printf("I am son process ! My process id = %dn",getpid());
}
else
{
printf("I am father process ! My id = %dn",getpid());
}
return 0;
}
编译程序test1.c并运行后得到运行结果:
[u2342010345@localhost u2342010345]$ gcc -o test1 test1.c
[u2342010345@localhost u2342010345]$ ./test1
The Sum of m and n is:20
I am son process ! My process id = 4223
I am father process ! My id = 4222
我的问题是,为什么我将红体字部分改为printf("The Sum of m and n is:%d",m + n);
即将printf函数当中的'n'去掉之后为什么改语句执行了两次?
即运行结果为:
[u2342010345@localhost u2342010345]$ gcc -o test1 test1.c
[u2342010345@localhost u2342010345]$ ./test1
The Sum of m and n is:20I am son process ! My process id = 4554
The Sum of m and n is:20I am father process ! My id = 4553
确实不是很明白为什么会出现这样奇怪的结果,按道理
用fork函数创建子进程时,之前的语句不会再子进程中存在的。
|
printf并没有执行两次,问题在于它的缓冲机制。
printf的内容先输出到缓冲区,程序继续执行,然后系统选择一个合适的时机把缓冲区里的内容打印到屏幕,这样可以提高程序执行的效率。
fork的时候子进程要从父进程复制很多数据,缓冲区内容也在其中。
所以,区别就在于,fork的时候缓冲区的内容是否已经到了屏幕。如果还没有,那么缓冲区里的内容就会从父进程和子进程各自打印一次到屏幕。
n的作用就是清空缓冲区把所有内容打印到屏幕上。
printf的内容先输出到缓冲区,程序继续执行,然后系统选择一个合适的时机把缓冲区里的内容打印到屏幕,这样可以提高程序执行的效率。
fork的时候子进程要从父进程复制很多数据,缓冲区内容也在其中。
所以,区别就在于,fork的时候缓冲区的内容是否已经到了屏幕。如果还没有,那么缓冲区里的内容就会从父进程和子进程各自打印一次到屏幕。
n的作用就是清空缓冲区把所有内容打印到屏幕上。
|
如果去掉n
printf("The Sum of m and n is:%d",m + n);
fflush(stdout); // 强制清空缓冲区
pid_t = fork();
这样也只输出一次
printf("The Sum of m and n is:%d",m + n);
fflush(stdout); // 强制清空缓冲区
pid_t = fork();
这样也只输出一次
|
printf的缓冲有时候还会带来其他问题。比如:
void f() {}
int main()
{
printf("AAAn");
f();
printf("BBB");
*(int*)0 = 0;
}
我运行的结果只有AAA, 没有BBB。这是因为它还没来得及从缓冲区输出,程序就挂了。
如果调程序的时候遇到这种情况,就很可能是错误的怀疑是死在了函数f()里面。
void f() {}
int main()
{
printf("AAAn");
f();
printf("BBB");
*(int*)0 = 0;
}
我运行的结果只有AAA, 没有BBB。这是因为它还没来得及从缓冲区输出,程序就挂了。
如果调程序的时候遇到这种情况,就很可能是错误的怀疑是死在了函数f()里面。
|
没有加n的时候 The Sum of m and n is:20在缓冲里面没输出,
fork的时候子进程拷贝了父进程的数据,所以父子进程的缓冲里面
都有The Sum of m and n is:20,在各自打印的时候就变成你的样子了
fork的时候子进程拷贝了父进程的数据,所以父子进程的缓冲里面
都有The Sum of m and n is:20,在各自打印的时候就变成你的样子了
|
fork后子进程会保留父进程的缓冲区;
标准输出默认是行缓冲,有两种情况会冲洗缓冲区并把数据输出到设备:1,当缓冲区满时,2,当遇到'n'字符时。
可以用下面的代码试一下
但当打印的字符串足够长时(充满缓冲区),字符串还是会被打印出来的。
标准输出默认是行缓冲,有两种情况会冲洗缓冲区并把数据输出到设备:1,当缓冲区满时,2,当遇到'n'字符时。
可以用下面的代码试一下
int main(void)
{
printf("Hello World!");
while(1);
return 0;
}
#include
int main(void)
{
printf("Hellon");
printf("World");
while(1);
return 0;
}
但当打印的字符串足够长时(充满缓冲区),字符串还是会被打印出来的。
|
参见APUE 172页
|
介绍得比较专业!