Fibonacci序列是0, 1, 1, 2, 3, 5, 8, .... ,通常它可以表示为:
f ib0 = 0
f ib1 = 1
f ibn= f ibn−1 + f ibn−2
编写一个C程序,使用系统调用fork()创建两个子进程P1和P2。他们的任务如下:
1) 子进程P1打印自己的pid,然后使用exec(族)系统调用显示当前目录下文件和子目录的详细信息。
2) 子进程P2中生成Fibonacci序列,序列的个数在程序命令行中作为参数传入,例如,参数为7,则子进程P2生成的Fibonacci序列为0、1、2、3、5、8、13。通过某种进程通信机制(共享内存、管道、消息等IPC机制),子进程P2把生成的Fibonacci序列发送给父进程,并由父进程输出(打印)Fibonacci序列。在父子进程通信的过程中必须实现同步,以使在子进程完成生成序列之前,父进程不会输出Fibonacci序列。使用wait()系统调用可以实现进程间的简单同步。执行必要的错误检查以保证不会接受命令行参数传递来的负值。
采用fork()创建进程,进程在创建的时候共享了父进程的所有资源,包括PC程序计数器,这时候父子进程的程序计数器都是pid=fork()的等号上,也即MOVE操作上,只不过返回的值在内核代码中区分了返回的不同,父进程得到了>0的一个Pid_t,子进程为0.
通过pipe命令,利用管道进行通信
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <signal.h>
int main(int argc,const char* argv[])
{
if(argc != 2) //防止报错
{
printf("please cin a number :%s\n",argv[0]);
exit(EXIT_SUCCESS);
}
pid_t childpid1,childpid2;
int pfd[2];//管道
int n = atoi(argv[1]); //获得参数
childpid1 = fork();
if( childpid1 < 0)
{
perror("fork_child1");
exit(EXIT_FAILURE);
}
else if( childpid1 == 0)
{
printf("childpid1 is:%d",getpid());
execlp("/bin/ls", "/bin/ls", "-R", ".", NULL);
}
else
{
pipe(pfd);
wait(NULL);
childpid2 = fork();
if(childpid2 < 0)
{
perror("fork_child2");
exit(EXIT_FAILURE);
}
else if( childpid2 == 0)
{
int next = 1;
int now = 0;
int tmp = 0;
int i;
close(pfd[0]);
for(i = 0; i < n; i++)
{
write(pfd[1],&now,sizeof(now));
tmp = now;
now = next;
next += tmp;
}
}
else
{
wait(NULL);
close(pfd[1]);
int i;
int status;
for(i = 0; i < n-1; i++)
{
int ret;
ret = read(pfd[0],&status,sizeof(status));
if(ret < 0)
{
perror("read");
exit(EXIT_FAILURE);
}
printf("%d、",status);
}
int ret = read(pfd[0],&status,sizeof(status));
if(ret < 0)
{
perror("read");
exit(EXIT_FAILURE);
}
printf("%d\n",status);
}
}
return EXIT_SUCCESS;
}