河南英文网站建设公司,沈阳网站开发外包,机机票网站建设,杭州 建设网站首页文章目录 一. 实验目的二. 实验内容三. 实验步骤四. 实验结果 一. 实验目的
#xff08;1#xff09;加深对进程概念的理解#xff0c;进一步认识并发执行的实质。 #xff08;2#xff09;掌握Linux 操作系统中进程的创建和终止操作。 #xff08;3#xff09;理解进程… 文章目录 一. 实验目的二. 实验内容三. 实验步骤四. 实验结果 一. 实验目的
1加深对进程概念的理解进一步认识并发执行的实质。 2掌握Linux 操作系统中进程的创建和终止操作。 3理解进程间通信的概念和方法。 4掌握常用的Linux 进程间通信的方法。
二. 实验内容
1编写一个C程序并使用系统调用fork()创建一个子进程。要求如下
① 在子进程中分别输出当前进程为子进程的提示、当前进程的PID 和父进程的PID、根据用户输入确定当前进程的返回值、退出提示等信息。 ② 在父进程中分别输出当前进程为父进程的提示、当前进程的PID 和子进程的PID、等待子进程退出后获得的返回值、退出提示等信息。
2编写C程序使用Linux中的IPC机制完成 “石头、剪子、布”的游戏。
三. 实验步骤
1编写一个C程序并使用系统调用fork()创建一个子进程。
程序设计
#include unistd.h
#include sys/types.h
#include errno.h
#include sys/wait.h
#include stdlib.h
#include stdio.hint main()
{pid_t childpid;int retval;int status;childpidfork();if(childpid0) // 子进程{printf(CHILD: I am the child process\n);printf(CHILD: My PID: %d\n, getpid());printf(CHILD: My parents PID: %d\n, getppid());printf(CHILD: The value of fork return is: %d\n, childpid);printf(CHILD: Sleep for 1 second ..\n);sleep(1);printf(CHILD: Enter an exit value (0~255):);scanf(%d,retval);printf(CHILD: Goodbye!\n);exit(retval);}else if(childpid0) // 父进程{printf(PARENT: I am the parent process\n);printf(PARENT: My PID: %d\n, getpid());printf(PARENT: my childs PID:%d\n, childpid);printf(PARENT: I will now wait for my child to exit.\n);wait(status);printf(PARENT: childs exit code is:%d\n,WEXITSTATUS(status));printf(PARENT: Goodbye\n);exit(0);}else // 错误处理{perror(fork error\n);exit(0);}return 0;
}
程序分析 该程序展示了一个父子进程之间的通信方式。它使用了fork()函数创建了子进程并在子进程中输出一些信息最后子进程通过exit()函数返回一个退出值。在父进程中它等待子进程的退出并通过wait()函数获取子进程退出的状态码。 首先是fork()函数的调用它会返回一个值该值有不同的含义 返回值为0时表示当前进程是子进程。返回值大于0时表示当前进程是父进程返回值为子进程的PID。返回值小于0时表示创建进程失败。 在子进程中它会输出一些信息包括它自己的PID和父进程的PID以及fork()函数的返回值。然后它会等待1秒钟让父进程有时间执行并输出信息。接下来它通过scanf()函数读取一个退出值并通过exit()函数返回。 在父进程中它会输出自己的PID和子进程的PID并等待子进程退出。它通过wait()函数获取子进程退出时的状态码。wait()函数会阻塞当前进程直到任意一个子进程退出。如果不关心哪个子进程退出可以使用wait(NULL)。在该程序中使用了status来获取子进程退出的状态码并通过WEXITSTATUS(status)函数获取子进程通过exit()函数返回的退出值。 最后父进程输出子进程的退出值并通过exit()函数退出进程。 总的来说该程序展示了fork()函数创建子进程、子进程的输出、父进程等待子进程退出和获取子进程退出的状态码等基本操作。 2编写C程序使用Linux中的IPC机制完成 “石头、剪子、布”的游戏。
程序设计
#include time.h
#include sys/types.h
#include sys/wait.h
#include sys/ipc.h#include sys/msg.h
#include stdio.h
#include stdlib.h
#include errno.h
#include unistd.hstruct Game
{int Round;long Type;
};void result_send(int num)
{struct Game game;game.Type1;game.Round rand()%3;int ret-1;retmsgsnd(num,game,sizeof(int),0);printf(%d msgsnd %d return %d\n,num,game.Round,ret);}int result_announce(int a,int b)
{if ((a1b) ||(a-2b))return -1;else if(ab)return 0;elsereturn 1;
}void writefile(int *result_list,int len)
{int count_A0;int count_B0;int pingju0;FILE *fin;finfopen(result.txt,w);if(finNULL) printf(This file wasnt opened);int i;for(i0;ilen;i){switch(result_list[i]){case -1:count_A;fprintf(fin,No.%d: A win\n,i1);printf(No.%d: A win\n,i1);break;case 0:pingju;fprintf(fin,No.%d: end in a draw\n,i1);printf(No.%d: end in a draw\n,i1);break;case 1:count_B;fprintf(fin,No.%d: B win\n,i1);printf(No.%d: B win\n,i1);break;}}printf(\nThe final result is A win:%ds \nB win:%ds \nend in a draw %ds\n,count_A,count_B,pingju);fprintf(fin,\nThe final result is A win: %ds \nB win: %ds \nend in a draw %ds\n,count_A,count_B,pingju);fclose(fin);
}int main()
{int times;int key11234;int key25678;int *result_list;pid_t pid1,pid2;int msgid1,msgid2;msgid1msgget(key1,IPC_CREAT | 0666);msgid2msgget(key2,IPC_CREAT | 0666);if(msgid1-1){fprintf(stderr,failed with error);exit(EXIT_FAILURE);}if(msgid2-1){fprintf(stderr,failed with error);exit(EXIT_FAILURE);}printf(Game start, please input rounds:);scanf(%d,times);printf(times%d\n,times);result_list(int*)malloc(times*sizeof(int));int i;for(i0;itimes;i){printf(********i%d********\n,i);pid1fork();if(pid10){//printf(in pid1:\n);int pidgetpid();printf(pid of pid1 is %d\n,pid);srand((unsigned)time(0)*3000);result_send(msgid1);exit(11);}pid2fork();if(pid20){//printf(in pid2:\n);int pidgetpid();printf(pid of pid2 is %d\n,pid);srand((unsigned)time(NULL)*i);result_send(msgid2);exit(22);}if(pid10 || pid20){fprintf(stderr,Fork Failed);printf(Fork failed!!);exit(-1);}else{//printf(in else before wait:\n);int status1,status2; wait(status1);//printf(wait1 ok, status1%d\n,WEXITSTATUS(status1));wait(status2);//printf(wait2 ok, status2%d\n,WEXITSTATUS(status2));struct Game game1,game2;msgrcv(msgid1,game1,sizeof(game1)-sizeof(long),0,0);printf(%d rcv %d ok\n,msgid1,game1.Round);msgrcv(msgid2,game2,sizeof(game2)-sizeof(long),0,0);printf(%d rcv %d ok\n,msgid2,game2.Round);int jresult_announce(game1.Round,game2.Round);result_list[i]j;printf(result_announce is %d.\n,j);}}//end forwritefile(result_list,times);if(msgctl(msgid1,IPC_RMID,0)-1)fprintf(stderr,msgctl(IPC_RMID) failed\n);if(msgctl(msgid2,IPC_RMID,0)-1)fprintf(stderr,msgctl(IPC_RMID) failed\n);exit(EXIT_SUCCESS);
}
程序分析 该程序是一个石头剪刀布游戏的模拟通过使用进程间通信机制实现了两个进程间的交互。程序创建了两个消息队列分别用于进程1和进程2向其父进程发送消息父进程接收消息并比较得出游戏结果然后输出到文件中。以下是程序的详细分析 首先定义了一个结构体Game用于存储比赛的轮数和玩家出的手势可以看作一个消息的格式。游戏结果用一个int型数组result_list来存储其中0表示平局-1表示A胜利1表示B胜利。然后是result_send函数它用于向指定的队列发送一条Game类型的消息。随机产生一个0~2的整数表示玩家出的手势并设置Type为1表示这是来自进程1的消息。返回值表示发送操作是否成功。 result_announce函数用于比较两个玩家出的手势返回值为0表示平局-1表示A胜利1表示B胜利。 writefile函数用于将游戏结果写入文件result.txt中同时输出到控制台。其中count_A、count_B、pingju分别表示A胜利的次数、B胜利的次数和平局的次数。 在主函数中首先创建了两个消息队列然后询问玩家要进行多少轮游戏并分配result_list数组的大小。进入for循环后创建了两个子进程pid1和pid2分别代表进程1和进程2。 在子进程中通过调用srand()和result_send()函数来随机选择手势然后向父进程所绑定的消息队列中发送一条消息。为了让每次产生的随机数不同可以使用时间函数time()和进程id组合生成随机数的种子。 在父进程中首先通过wait()函数等待子进程1和子进程2都结束并获取它们退出时的状态值。然后使用msgrcv()函数从消息队列中接收子进程所发出的消息也就是两个玩家出的手势。 接下来调用result_announce()函数比较两个玩家出的手势获取比赛结果并将得到的结果保存到result_list数组中。 当所有的比赛都结束后调用writefile()函数来输出结果到result.txt文件中并输出到控制台。同时通过msgctl()函数删除之前创建的两个消息队列。 总的来说该程序运用了fork()函数创建子进程、消息队列实现进程间通信等基本操作。它模拟了石头剪刀布游戏的过程同时也展示了使用进程间通信机制进行协作的思路。 四. 实验结果
1编写一个C程序并使用系统调用fork()创建一个子进程。 2编写C程序使用Linux中的IPC机制完成 “石头、剪子、布”的游戏。