循序渐进学unix——上机记录(二)
这次的主角是fork。相信每个unix的学习者都绕不过这个函数。此函数创建一个子进程,与父进程共享代码区,但是有自己单独的数据区和栈区。此函数在父进程中返回子进程的pid,而在子进程中却返回0。这恐怕是最让初学者们难以理解的地方了。正是因为这个性质,fork在使用是总是出现在if else块中;以区分父进程和子进程需要执行的代码。
1,小试牛刀,在使用fork的前后打印出当前进程的pid(getpid)和ppid(getppid)。结果很容易发现子进程中的ppid即为父进程的pid
#include<unistd.h> #include<stdio.h> #include<sys/stat.h> #include<sys/types.h> #include <stdlib.h> void main( int argc, char ** argv ) { int val_fork; printf("PID = %d\n", getpid()); printf("PPID = %d\n", getppid()); printf("No° de propriétaire = %d\n", getuid());//sb.st_uid); printf("No° de groupe = %d\n", sb.st_gid); if( (val_fork=fork())==0) { //section fils printf("Section fils : val_fork = %d\n", val_fork); printf("Section fils : PID = %d\n", getpid()); printf("Section fils : PPID = %d\n", getppid()); exit(0); }else { printf("Section pere : val_fork = %d\n", val_fork); printf("Section pere : PID = %d\n", getpid()); printf("Section pere : PPID = %d\n", getppid()); return; } }
2,写程序证明父子进程是同时执行的;即会出现交替的输出(使用sleep来把执行机会让给对方);使用wait使父进程在子进程之后结束。
#include<unistd.h> #include<stdio.h> #include<sys/stat.h> #include<sys/types.h> #include <stdlib.h> void main( int argc, char ** argv ) { int val_fork; int i; printf("PID = %d\n", getpid()); printf("PPID = %d\n", getppid()); if( (val_fork=fork())==0) { //section fils for ( i=0; i<10; i++) { printf("Section fils : PID = %d\n", getpid()); printf("Section fils : PPID = %d\n", getppid()); } exit(0); }else { for ( i=0; i<10; i++) { printf("Section pere : PID = %d\n", getpid()); printf("Section pere : PPID = %d\n", getppid()); } wait(); printf("Stop waiting!!!\n"); return; } }
3,多任务。计算(a + b) * (c + d) / (e + f)。其中
a + b 由儿子1计算
c + d 由儿子1计算
e + f 由儿子1计算
* 和 / 由父亲计算。
这个就稍微有点意思了,只允许实使用最简单的进程间通讯方式。
- 变量的传入不是问题,因为子进程本来就有一份父进程的数据拷贝。
- 子进程计算完的结果如何返回给父进程?可以利用waitpid函数。父进程分别等待相应的子进程结束,并提取收到的返回值。详细使用方法需阅读man wait
代码
#include<unistd.h> #include<stdio.h> #include<sys/stat.h> #include<sys/types.h> #include <stdlib.h> int main( int argc, char ** argv ) { int val_fork1, val_fork2, val_fork3; int i, res_fils1, res_fils2, res_fils3, res; int a = atoi(argv[1]); int b = atoi(argv[2]); int c = atoi(argv[3]); int d = atoi(argv[4]); int e = atoi(argv[5]); int f = atoi(argv[6]); if( (val_fork1=fork())==0) { res = a+b; printf("Fils 1 : a + b = %d\n", res); return(res); } else { if( (val_fork2=fork())==0) { res = c+d; printf("Fils 2 : c + d = %d\n", res); exit(res); } if( (val_fork3=fork())==0) { res = e+f; printf("Fils 3 : e + f = %d\n", res); exit(res); } waitpid(val_fork1, &res_fils1, 0); waitpid(val_fork2, &res_fils2, 0); waitpid(val_fork3, &res_fils3, 0); //printf("%d, %d, %d\n\n", WEXITSTATUS(res_fils1) , res_fils2 , res_fils3); printf("Résultat final = %d\n", WEXITSTATUS(res_fils1) *WEXITSTATUS(res_fils2) / WEXITSTATUS(res_fils3)); return; } }
先到这,有时间继续!