process and memory 对控制台输入echo hello的流程简单剖析

int pid = fork();

if(pid > 0){

printf("parent: child=%d\n", pid);

pid = wait();

printf("child %d is done\n", pid);

} else if(pid == 0){

printf("child: exiting\n");

exit();

} else {

printf("fork error\n");

}

fork 创建一个新的进程返回两个值 并且共享相同的代码 相当于两个线程同时执行

在父进程中 pid值为子进程的pid

在子进程中 则pid的值为0

输出结果:

parent: child=1234

child: exiting

这种结果是 父进程执行到pid = wait();时候等待子进程退出 但是子进程没有退出

子进程中pid =0 就会执行else if(pid==0)的语句

parent: child 1234 is done这种结果是父进程执行到pid = wait()

子进程已经退出 不在运行了 所以只有父进程一个进程在运行 按顺序执行。

exit函数调用退出进程 并且释放进程占用的资源

System call      Description

fork()                  Create process

exit()                         Terminate current process

wait()                Wait for a child process to exit

kill(pid)             Terminate process pid

getpid()           Return current process’s id

sleep(n)         Sleep for n seconds

exec(filename, *argv)             Load a file and execute it

sbrk(n)                        Grow process’s memory by n bytes

open(filename, flags)                 Open a file; flags indicate read/write

read(fd, buf, n)                            Read n byes from an open file into buf

write(fd, buf, n)                           Write n bytes to an open file

close(fd)                                    Release open file fd

dup(fd)                                       Duplicate fd

pipe(p)                                 Create a pipe and return fd’s in p

chdir(dirname)                       Change the current directory

mkdir(dirname)                              Create a new directory

mknod(name, major, minor)                Create a device file

fstat(fd)                                       Return info about an open file

link(f1, f2)                                 Create another name (f2) for the file f1

unlink(filename)                       Remove a file

char *argv[3];

argv[0] = "echo";

argv[1] = "hello";

argv[2] = 0;

exec("/bin/echo", argv);

printf("exec error\n");

这个代码 执行/bin/echo 这个程序并且带有一个参数列表。 echo hello这个参数第一个参数echo可以忽视 大部分程序第一个参数

和程序名一样可以忽略

shell实现echo hello 带参数的流程如下

8500 int main(void)

8502 {

8503 static char buf[100];

8504 int fd;

8505//在主循环中 用geccmd 读取命令行输入的内容

8506 // Assumes three file descriptors open.

8507 while((fd = open("console", O_RDWR)) >= 0){

8508 if(fd >= 3){

8509 close(fd);

8510 break;

8511 }

8512 }

8513

8514 // Read and run input commands.

//在主循环中 用geccmd 读取命令行输入的内容

8515 while(getcmd(buf, sizeof(buf)) >= 0){

8516 if(buf[0] == ’c’ && buf[1] == ’d’ && buf[2] == ’ ’){

8517 // Clumsy but will have to do for now.

8518 // Chdir has no effect on the parent if run in the child.

8519 buf[strlen(buf)-1] = 0; // chop \n

8520 if(chdir(buf+3) < 0)

8521 printf(2, "cannot cd %s\n", buf+3);

8522 continue;

8523 }

//创建一个子进程共享shell中 if下面的代码 此时子进程 执行runcmd 父进程处于wait状态

//如果用户输入 echo hello  则runcmd将以"echo hello"作为参数

8524 if(fork1() == 0)

8525     runcmd(parsecmd(buf));

8526 wait();

8527 }

8528 exit();

8529 }

下面为runcmd的代码

8404 // Execute cmd. Never returns.

8405 void

8406 runcmd(struct cmd *cmd)

8407 {

8408 int p[2];

8409 struct backcmd *bcmd;

8410 struct execcmd *ecmd;

8411 struct listcmd *lcmd;

8412 struct pipecmd *pcmd;

8413 struct redircmd *rcmd;

8414

8415 if(cmd == 0)

8416 exit();

8417

8418 switch(cmd->type){

8419 default:

8420 panic("runcmd");

8421//如果执行到这里的 话 就会执行exec(ecmd->argv[0], ecmd->argv);函数 则就会用echo程序 代替主程序中的runcmd程序 在echo

//中调用exit 函数造成子进程结束 父进程 wait()状态也将会结束掉 因为wait函数一直会等到子进程挂掉 并且返回子进程的pid

8422 case EXEC:

8423 ecmd = (struct execcmd*)cmd;

8424 if(ecmd->argv[0] == 0)

8425 exit();

8426 exec(ecmd->argv[0], ecmd->argv);

8427 printf(2, "exec %s failed\n", ecmd?>argv[0]);

8428 break;

8429

8430 case REDIR:

8431 rcmd = (struct redircmd*)cmd;

8432 close(rcmd->fd);

8433 if(open(rcmd->file, rcmd->mode) < 0){

8434 printf(2, "open %s failed\n", rcmd?>file);

8435 exit();

8436 }

8437 runcmd(rcmd->cmd);

8438 break;

8439

8440 case LIST:

8441 lcmd = (struct listcmd*)cmd;

8442 if(fork1() == 0)

8443 runcmd(lcmd?>left);

8444 wait();

8445 runcmd(lcmd?>right);

8446 break;

8450 case PIPE:

8451 pcmd = (struct pipecmd*)cmd;

8452 if(pipe(p) < 0)

8453 panic("pipe");

8454 if(fork1() == 0){

8455 close(1);

8456 dup(p[1]);

8457 close(p[0]);

8458 close(p[1]);

8459 runcmd(pcmd?>left);

8460 }

8461 if(fork1() == 0){

8462 close(0);

8463 dup(p[0]);

8464 close(p[0]);

8465 close(p[1]);

8466 runcmd(pcmd?>right);

8467 }

8468 close(p[0]);

8469 close(p[1]);

8470 wait();

8471 wait();

8472 break;

8473

8474 case BACK:

8475 bcmd = (struct backcmd*)cmd;

8476 if(fork1() == 0)

8477 runcmd(bcmd?>cmd);

8478 break;

8479 }

8480 exit();

8481 }

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-07 00:52:06

process and memory 对控制台输入echo hello的流程简单剖析的相关文章

java.util.Scanner应用详解++扫描控制台输入

java.util.Scanner应用详解 java.util.Scanner是Java5的新特征,主要功能是简化文本扫描.这个类最实用的地方表现在获取控制台输入,其他的功能都很鸡肋,尽管Java API文档中列举了大量的API方法,但是都不怎么地. 一.扫描控制台输入 这个例子是常常会用到,但是如果没有Scanner,你写写就知道多难受了. 当通过new Scanner(System.in)创建一个Scanner,控制台会一直等待输入,直到敲回车键结束,把所输入的内容传给Scanner,作为扫

获取在控制台输入命令后的结果

背景:在控制台输入命令如查询手机设备的命令,需要获取到控制台的内容 实现代码,主要是当文件流的方式实现 public static void main(String[] args) { Process process = null; List<String> processList = new ArrayList<String>(); System.out.println("执行命令开始:"); try { process = Runtime.getRuntim

(六)read读取控制台输入

1.基本语法 read(选项)(参数) 选项: -p:指定读取值时的提示符: -t:指定读取值时等待的时间(秒). 参数 变量:指定读取值的变量名 2.案例实操 (1)提示7秒内,读取控制台输入的名称 [atguigu@hadoop101 datas]$ touch read.sh [atguigu@hadoop101 datas]$ vim read.sh #!/bin/bash read -t 7 -p "Enter your name in 7 seconds " NAME ec

5、shell-read读取控制台输入

1.基本语法 read(选项)(参数) 选项: -p:指定读取值时的提示符: -t:指定读取值时等待的时间(秒). 参数 变量:指定读取值的变量名 2.案例实操 (1)提示7秒内,读取控制台输入的名称 [[email protected] datas]$ touch read.sh [[email protected] datas]$ vim read.sh #!/bin/bash read -t 7 -p "Enter your name in 7 seconds " NAME ec

再论流之读取控制台输入

在java1.0中,执行控制台输入的唯一方法是使用字节流.现在仍然可以使用字节流读取控制台输入.但是,对于商业应用程序,读取控制台输入的更好方法是使用面向字符的流.使用面向字符的流可以使程序更容易国际化和维护. 在Java中,控制台输入是通过从System.in读取完成的.为了获得与控制台关联的基于字符的流.可以在BufferedReader对象中封装System.io.BufferedReader支持缓存的输入流.通常使用的构造函数如下所示: BufferedReader(Reader inp

Java--分支语句、循环、数组、控制台输入语句、常用数学函数

**-----本章节-----** 1.分支语句 2.循环 3.数组 4.控制台输入语句 5.部分常用的数学函数 ============================================================== 一分支语句 1.概念 (1)分支语句又称条件语句条件语句使部分程序可根据某些表达式的值被有选择地执行. (2)Java编程语言支持双路 if和多路 switch 分支语句. ===========================================

将控制台输入的每一行字符串,输出至txt文件当中

/** *    需求:将控制台输入的每一行字符串,输出至txt文件当中. /** * 需求:将控制台输入的每一行字符串,输出至txt文件当中. * 思路: * 1.首先想到BufferReader高级流读取一行字符串readLine方法. * 2.但是前提依赖于字符转换流ISR和低级节点流,这里是从控制台输入,节点流自然是System.in.如果是从文件输入,则节点流换成FIS即可 * 3.这样就能建立一条输入流了.BufferedReader(new InputStreamReader(Sy

2016/1/10 实例 1,控制台 输入人数 2,控制台 输入对应人数的成绩 3,求成绩总和以及最大值 最小值 平均值

1 import java.util.Scanner; 2 3 4 public class KongZhitai { 5 6 7 public static void main(String[] args) { 8 // TODO 自动生成的方法存根 9 10 //第一步 输出 扫描 接收 人数 11 int number=0; //定义变量 12 System.out.println("请输入人数:"); 13 Scanner arr=new Scanner(System.in);

java 怎么实现接收控制台输入?

//接收键盘输入: //怎么实现接收控制台输入? import java.util.Scanner; //Test.java import java.util.Scanner; public class Test16{ public static void main(String args[]){ System.out.println("input a number:"); Scanner in =new Scanner(System.in); int x1=in.nextInt();