日期:2014-05-16  浏览次数:20826 次

循序渐进学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;
	}
}


先到这,有时间继续!