1、printf函数输出问题
printf 函数并不会直接将数据输出到屏幕,而是先放到缓冲区中,只有一下三种情况满足,才会输出到屏幕。
- 缓冲区满
- 强制刷新缓冲区 fflush
- 程序结束时
2、主函数参数介绍
int main( int argc, char* argv[ ], char* envp[ ])
- argc 参数个数
- argv 参数内容
- envp 环境变量
3、复制进程 fork
3.1 fork 方法
pid_t fork(void)
函数返回类型 pid_t 实质是 int 类型,Linux 内核2.4.0版本的定义是:
fork 函数会新生成一个进程,调用 fork 函数的进程为父进程,新生成的进程为子进程。在父进程中返回子进程的 pid,在子进程中返回 0,失败返回-1。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
int main(int argc, char* argv[],char* envp[])
{
char * s = NULL;
int n = 0;
pid_t pid = fork();
assert( pid != -1 );
if ( pid == 0 )
{
s = "child";
n = 4;
}
else
{
s = "parent";
n = 7;
}
int i = 0;
for(; i < n; i++ )
{
printf("pid=%d,n=%d,&n=%x,s=%s\n",getpid(),n,&n,s);
sleep(1);
}
exit(0);
}
总结:
- 复制从 fork 执行结束开始,父进程中 fork 的返回值为子进程(pid)的 id 号,子进程的返回值为 0。
- 在进程中打印的变量地址,都是逻辑地址,不是物理地址。
- 子进程会复制父进程的内存空间。
3.2 fork练习
下列程序输出几个 “ A ” ?
(1)
int main(int argc, char* argv[],char* envp[])
{
int i = 0;
for( ; i < 2; i++ )
{
fork();
printf("A\n");
}
exit(0);
}
一共打印 6 个 A
(2)
int main(int argc, char* argv[],char* envp[])
{
int i = 0;
for( ; i < 2; i++ )
{
fork();
printf("A");
}
exit(0);
}
打印 6 个 A
printf(“A”) 没有 “ \n ”,不会直接将A打印发哦屏幕,会先放到缓冲区,fork 复制进程时会复制缓冲区存放的A
(3)
int main()
{
fork() || fork();
printf("A\n");
exit(0);
}
会打印出 3 个 A 。
分析: 首先从fork() || fork()进入左边的fork,返回值不为0,复制得到子进程,父进程因为或的关系,直接打印A,对于子进程,左边的fork返回0,语句执行右边的fork ,在进行进程复制,此时子进程打印A,子进程的子进程,也打印A,结束。