This simulation homework focuses on fork.py, a simple process creation simulator that shows how processes are related in a single “familial” tree. Read the relevant README for details about how to run the simulator.
python fork.py -s 10 -c
python fork.py -s 10 -A a+b,b+c,c-,a+d -c
python fork.py -s 10 -f 0.1 -a 10 -c
python fork.py -s 10 -f 0.9 -a 10 -c
python3 fork.py -t -c
没有-R:d,e成为a的子进程
python fork.py -A a+b,b+c,c+d,c+e,c- -c
有-R:d,e成为b的子进程
python fork.py -A a+b,b+c,c+d,c+e,c- -R -c
python fork.py -F -c
python fork.py -t -F -c
In this homework, you are to gain some familiarity with the process management APIs about which you just read. Don’t worry – it’s even more fun than it sounds! You’ll in general be much better off if you find as much time as you can to write some code, so why not start now?
说明父进程和子进程拥有相同但是独立的地址空间
父进程和子进程对x所做的任何改变都是独立的
- #include
- #include
-
- int main(void)
- {
- int x = 1;
-
- printf("x is: %d\n", x);
-
- x = 100;
-
- int rc = fork();
-
- if (rc == 0)
- {
- printf("Hello, i am child (pid: %d)\n", getpid());
- printf("old x is %d\n", x);
- x++;
- printf("now x is %d\n", x);
- }
- else
- {
- printf("Hello, i am parent of %d (pid: %d)\n", rc, getpid());
- printf("old x is %d\n", x);
- x--;
- printf("now x is %d\n", x);
- }
-
- return 0;
- }
子进程和父进程共享文件,父进程打开了文件a.txt而子进程继承了这个文件,因此也可以写入
假设父进程先运行的话,子进程的写入不会覆盖父进程
子进程先运行,父进程的写入同样也不会覆盖子进程
- #include
- #include
- #include
- #include
- #include
-
- int main(void)
- {
- int fd = open("a.txt", O_RDWR, 2);
- int rc = fork();
-
- if (rc == 0)
- {
- printf("Hello! i am child (pid: %d)\n", getpid());
- char* str1 = "de";
- write(fd, str1, 2);
- }
- else
- {
- printf("Hello! i am parent of %d (pid: %d)\n", rc, getpid());
- char* str2 = "fgh";
- write(fd, str2, 3);
- }
-
- return 0;
- }
vfork() :与 fork() 一样创建一个子进程,但保证子进程先运行,只有子进程调用 exec 或 exit 后, 父进程才会被调用
- #include
- #include
- #include
-
- int main(void)
- {
- int rc = vfork();
-
- if (rc == 0)
- {
- printf("Hello! i am child (pid: %d)\n", getpid());
- exit(0);
- }
- else
- {
- printf("Goodbye! i am parent of %d (pid: %d)\n", rc, getpid());
- }
-
- return 0;
- }
- #include
- #include
-
- int main(void)
- {
- printf("hello world (pid:%d)\n",(int)getpid());
- int rc = fork();
- if(rc < 0)
- {
- fprintf(stderr,"fork failed\n");
- exit(1);
- }else if(rc == 0)
- {
- printf("hello, I am child (pid:%d)\n",(int)getpid());
- char *path = "/bin/ls";
- char* myargs[3] = {"ls","-l",NULL};
- char* env[] = {"PATH=/bin:/bin/usr",NULL};
- execl("/bin/ls","ls","-l",NULL);
- execv(path,myargs);
- execlp("ls","ls","-l",NULL);
- execvp(myargs[0],myargs);
- execle("/bin/ls","ls","-l",NULL,env);
- execvpe(myargs[0],myargs,env);
- printf("This shouldn't print out\n");
- }else
- {
- int rc_wait = wait(NULL);
- printf("hello, I am parent of %d (rc_wait:%d) (pid:%d)\n",
- rc,rc_wait,(int)getpid());
- }
-
- exit(0);
- }
父进程调用wait()
- #include
- #include
- #include
- #include
- #include
-
- int main(void)
- {
- int rc = fork();
-
- if (rc == 0)
- {
- printf("Hello! i am child (pid: %d)\n", getpid());
- }
- else
- {
- int wc = wait(NULL);
- printf("Hello! i am parent of %d (wc: %d) (pid: %d)\n", rc, wc, getpid());
- }
-
- return 0;
- }
子进程调用wait(),wait()会返回-1,并且设置errno为ECHILD
- #include
- #include
- #include
- #include
- #include
- #include
-
- int main(void)
- {
- int rc = fork();
-
- if (rc == 0)
- {
- int wc = wait(NULL);
- printf("Hello! i am child (wc: %d) (pid: %d)\n", wc, getpid());
- }
- else
- {
- printf("Hello! i am parent of %d (pid: %d)\n", rc, getpid());
- }
-
- if (errno == ECHILD)
- {
- printf("No child!\n");
- }
-
- return 0;
- }
wait()等价于waitpid(-1, &status, 0)
- #include
- #include
- #include
- #include
- #include
- #include
-
- int main(void)
- {
- int status;
- int rc = fork();
- int wc = waitpid(-1, &status, 0);
-
- if (rc == 0)
- {
- printf("Hello! i am child (wc: %d) (pid: %d)\n", wc, getpid());
- }
- else
- {
- printf("Hello! i am parent of %d (wc: %d) (pid: %d)\n", wc, rc, getpid());
- }
-
- if (errno == ECHILD)
- {
- printf("No child!\n");
- }
-
- return 0;
- }
在子进程中关闭标准输出,不会影响到父进程的输出
- #include
- #include
- #include
-
- int main(void)
- {
- int rc = vfork(); //让子进程先运行,看看对父进程有什么影响
-
- if (rc == 0)
- {
- printf("Hello! i am child (pid: %d)\n", getpid());
- close(STDOUT_FILENO);
- printf("What happend?\n");
- exit(0);
- }
- else
- {
- printf("Hello! i am parent of %d (pid: %d)\n", rc, getpid());
- }
-
- return 0;
- }
- #include
- #include
-
- int main(void)
- {
- int p[2];
- int pid1;
- int pid2;
-
- pipe(p);
-
- pid1 = fork();
-
- if(pid1 == 0)
- {
- close(p[0]);
- write(p[1],"hello\n",6);
- exit(0);
- }
-
- pid2 = fork();
-
- int buf[10];
- if(pid2 == 0)
- {
- close(p[1]);
- read(p[0],buf,6);
- printf("%s",buf);
- exit(0);
- }
-
- wait(NULL);
- wait(NULL);
-
- exit(0);
- }