2009-2010学年第一学期
专 业:网络工程
班 级:071022
学 号:07102210
姓 名:刘辰龙
提交日期:2009.12.04
实验一、Linux进程创建与进程通信
【实验目的】
1. 熟悉有关Linux系统调用;
2. 学习有关Linux的进程创建,理解进程创建后两个并发进程的执行;
3. 通过系统调用wait()和exit(),实现父子进程同步;
4. 掌握管道、消息缓冲等进程通信方法并了解其特点和使用。
【实验程序及分析】
1. 父进程创建子进程
实现父进程创建一个子进程,返回后父子进程分别循环输出字符串“The parent process.”及“The child process.”5次,每次输出后使用sleep(1)延时一秒,然后再进入下一次循环。给出源程序代码和运行结果。
程序代码:
#include main() { int p,i; while((p=fork())==-1); //创建子进程直至成功 if(p==0) //子进程返回 { for(i=0;i<5;i++) { printf("The child process!\\n"); sleep(1); //延时1秒 } } else{ //父进程返回 for(i=0;i<5;i++) { printf("The parent process!\\n"); sleep(1); //延时1秒 } } } 运行结果: 2. 父子进程同步 修改上题程序,使用exit()和wait()实现父子进程同步,其同步方式为父进程等待子进程的同步,即:子进程循环输出5次,然后父进程再循环输出5次。给出源程序代码和运行结果。 程序代码: #include main() { int p,i; while((p=fork())==-1); //创建子进程直至成功 if(p>0) //返回父进程 { wait(0); //父进程等待子进程终止 for(i=0;i<5;i++) { printf("The parent process!\\n"); sleep(1); //延时1秒 } } else //返回子进程 { for(i=0;i<5;i++) { printf("The child process!\\n"); sleep(1); } exit(0); //子进程向父进程发终止信号0 } } 运行结果: 3. Linux管道通信 编写一个程序,实现以下功能。给出源程序代码和运行结果。 (1)父进程使用系统调用pipe()创建一个无名管道; (2)创建两个子进程,分别向管道发送一条信息后结束; 子进程1发送:Child 1 is sending a message to parent! 子进程2发送:Child 1 is sending a message to parent! (3)父进程从管道中分别接收两个子进程发来的消息并显示在屏幕上,父进程结束。两个子进程发送信息没有先后顺序要求。 程序代码: #include #include main() { int p1,p2,fd[2]; char outpipe[50]; //定义读缓冲区 char inpipe1[50]="Child 1 is sending a message to parent!";//定义写缓冲区1 char inpipe2[50]="Child 2 is sending a message to parent!";//定义写缓冲区2 pipe(fd); //创建无名管道 while((p1=fork())==-1); //创建子进程1 if(p1==0) //子进程1返回 { write(fd[1],inpipe1,50); //写信息到管道 exit(0); } else{ while((p2=fork())==-1); //创建子进程2 if(p2==0) //子进程2返回 { write(fd[1],inpipe2,50);//写信息到管道 exit(0); } else { wait(0); //等待子进程结束 read(fd[0],outpipe,50); //从管道读信息到读缓冲区 printf("%s\\n",outpipe); //显示读出的信息 wait(0); read(fd[0],outpipe,50); printf("%s\\n",outpipe); } } } 运行结果: 4. Linux消息缓冲通信 编写一个程序,实现以下功能。给出源程序代码和运行结果。 (1)父进程创建一个消息队列和一个子进程,由子进程发送消息,父进程等待子进程结束后接收子进程发来的消息,并显示消息内容。以“end”作为结束消息。 程序代码: #include #include #include #include #include #include #define MAXMSG 512 //定义消息长度 struct my_msg //定义消息缓冲区数据结构 { long int my_msg_type; char some_text[MAXMSG]; }msg; main() { int p; int msgid; //定义消息缓冲区内部标识 char buffer[BUFSIZ]; //定义用户缓冲区 msgid=msgget(1234,0666|IPC_CREAT); //创建消息队列,key为1234 long int msg_to_receive=0; while((p=fork())==-1); if(p==0){ while(1) { puts("Enter some text:"); //提示键入消息内容 fgets(buffer,BUFSIZ,stdin); //标准输入送buffer msg.my_msg_type=1; //设置消息类型为1 strcpy(msg.some_text,buffer); //buffer送消息缓冲 msgsnd (msgid,&msg,MAXMSG,0); //发送消息到消息队列 if(strncmp(msg.some_text,"end",3)==0) /消息为“end”则结束 break; } exit(0); } else{ wait(0); while (1) { msgrcv (msgid, &msg, BUFSIZ, msg_to_receive, 0); //接收消息 printf ("You wrote:%s",msg.some_text); //显示消息 if (strncmp (msg.some_text,"end",3)==0) //消息为“end”则结束 break; } msgctl (msgid, IPC_RMID,0); //撤消消息队列 } } 运行结果: 2)分别编写发送进程和接收进程,由发送进程发送消息,接收进程接收消息。采用先执行发送进程后执行接收进程的方式同步。以“end”作为结束消息。 程序代码: ① 发送进程: #include #include #include #include #include #include #define MAXMSG 512 //定义消息长度 struct my_msg //定义消息缓冲区数据结构 { long int my_msg_type; char some_text[MAXMSG]; }msg; main( ) { int msgid; //定义消息缓冲区内部标识 char buffer[BUFSIZ]; //定义用户缓冲区 msgid=msgget(1234,0666|IPC_CREAT); //创建消息队列,key为1234 while(1) { puts("Enter some text:"); //提示键入消息内容 fgets(buffer,BUFSIZ,stdin); //标准输入送buffer msg.my_msg_type=1; //设置消息类型为1 strcpy(msg.some_text,buffer); //buffer送消息缓冲 msgsnd (msgid,&msg,MAXMSG,0); //发送消息到消息队列 if(strncmp(msg.some_text,"end",3)==0) /消息为“end”则结束 break; } exit(0); } 运行结果: 接收进程: #include #include #include #include #include #include #define MAXMSG 512 //定义消息长度 struct my_msg //定义消息f缓冲区数据结构 { long int my_msg_type; char some_text[MAXMSG]; }msg; main() { int msgid; //定义消息缓冲区内部标识 long int msg_to_receive=0; msgid=msgget(1234, 0666|IPC_CREAT); //获取消息队列,key为1234 while (1) { msgrcv (msgid, &msg, BUFSIZ, msg_to_receive, 0); //接收消息 printf ("You wrote:%s",msg.some_text); //显示消息 if (strncmp (msg.some_text,"end",3)==0) //消息为“end”则结束 break; } msgctl (msgid, IPC_RMID,0); //撤消消息队列 exit (0); } 运行结果: