练习使用Linux系统调用函数创建进程、加载程序、终止进程、撤销进程,利用信号机制定制突发事件处理的编程,编写用信号机制对动态产生的进程实施管理,掌握多进程并发编程的基本方法。
先创建用户家目录下创建文件名为“姓名+学号+05”的子目录,作为本次实验目录,本次实验的所有代码都放到该目录下。要求将所有源代码与数据文件打包成文件”学号-姓名-lab5.tar.gz”, 压缩包与实验报告分别上传到指定目录下。
p1:I am father process
p11: 当前时间是< 年 月 日 时 分 秒>
p12: I am young brother process
p121:我的学号是<您的学号xxx>
p122:我的姓名是<您的姓名xxx>
提示:获得当前系统时间的函数是 time_t time(time_t *t); 将time_t类型的的时间转换成时间字符串的函数是:char *ctime(const time_t *timep); 其使用方法见教材3.2.4
(1)打印提示符%;获取用户输入指令;解析指令;寻找命令文件,执行指令
(1)显示命令提示符%;
(2)获取用户输入指令;解析指令;寻找命令文件,执行指令;
(3)前一个命令完成后才继续显示命令提示符%,等待用户输入下一条命令;
(3)如果输入“exit”或“logout”,则退出shell.
(4)允许命令参数间有多个空格,也允许命令前后有空格
(5)支持输出重定向和管道功能。
提示:可参考上一次实验分解命令行的代码
由父进程创建两个子进程,通过终端输入Crtl+\组合键向父进程发送SIGQUIT软中断信号或由系统时钟产生SIGALRM软中断信号发送给父进程;父进程接收到这两个软中断的其中某一个后,向其两个子进程分别发送整数值为SIGUSR1 (10)和SIGUSR1 (12)软中断信号,子进程获得对应软中断信号后,分别输出“<进程PID> killed by <信号编号>”后,终止运行;父进程调用wait()函数等待两个子进程终止,然后自我终止。
- 命令1:功能是创建一批子进程,格式为“create <进程数>” ,命令执行成功后,显示所有新创建子进程PID。比如“create 10”表示创建10个子进程,子进程执行的代码可以为:“while(1){};exit(100);”
2)命令2:终止一批子进程,格式为“kill …”(如“kill 123 456 789”为终止PID号为123、456、789的三个子进程),子进程显示“killed by parent”后终止,父进程通过SIGCHLD信号处理程序等待子进程终止,显示终止的子进程PID。
3)命令3:显示当前子进程列表,命令格式为:“ps -u”
4)命令4:父进程终止命令,格式为“exit”,当所有子进程都结束后,才允许执行该命令。
提示:可用fgets函数将整个命令作为一行文本输入,再调用库函数(如strtok或strchr)将各个命令参数提取出来。
安装Linux操作系统的计算机
源代码
#include
#include
#include
#include
int main()
{
int p11,p12,p121,p122;
p11=fork();
if(p11==0)
{
time_t curtime;
time(&curtime);
printf("当前时间是%s\n", ctime(&curtime));
exit(0);
}
if(p11>0)
{
printf("I am father process\n");
p12=fork();
if(p12==0)
{
p121=fork();
if(p121==0)
{
printf("我的学号是201741404234\n");
exit(0);
}
p122=fork();
if(p122==0)
{
printf("我的姓名是李天赐\n");
exit(0);
}
printf("I am young brother process\n");
exit(0);
}
else
exit(0);
exit(0);
}
return 0;
}
源代码
#include
#include"wrapper.h"
#define MAXARGS 8192
#define MAXLINE 1000
void execute(char *cmdline)
{
char *argv[MAXARGS];
char buf[MAXLINE];
int bg;
pid_t pid;
strcpy(buf, cmdline);
bg = parseline(buf, argv);
if (argv[0] == NULL)
return;
if (!builtin_command(argv)){
if ((pid = fork()) == 0) {
if (execvp(argv[0],argv) < 0) {
printf("%s: Command not found.\n", argv[0]);
exit(0);
}
}
if (!bg) {
int status;
if (waitpid(pid,&status, 0) < 0)
perror("waitpid error");
}
else
printf("%d %s", pid, cmdline);
}
return;
}
int builtin_command(char **argv)
{
if (!strcmp(argv[0], "exit"))
exit(0);
if (!strcmp(argv[0], "logout"))
exit(0);
if (!strcmp(argv[0], "&"))
return 1;
return 0;
}
int parseline(char *buf, char **argv)
{
char *delim;
int argc;
int bg;
buf[strlen(buf)-1] = ' ';
while (*buf && (*buf == ' '))
buf++;
argc = 0;
while ((delim = strchr(buf,' '))) {
argv[argc++] = buf;
*delim = '\0';
buf = delim + 1;
while (*buf && (*buf == ' '))
buf++;
}
argv[argc] = NULL;
if (argc == 0)
return 1;
if ((bg = (*argv[argc-1] == '&')) != 0)
argv[--argc] = NULL;
return bg;
}
int main()
{
char cmdlime[MAXLINE];
while (1) {
printf("%%");
fgets(cmdlime,MAXLINE,stdin);
if (feof(stdin))
exit(0);
execute(cmdlime);
}
}
源代码
#include
#include
#include
void waiting( ),stop( );
int wait_mark;
main( )
{
int p1,p2,stdout;
signal(SIGQUIT,stop);
while((p1=fork())==-1); /*创建子进程p1*/
if (p1>0)
{
while((p2=fork())==-1); /*创建子进程p2*/
if(p2>0)
{
wait_mark=1;
/*接收到^c信号,转stop*/
waiting();
kill(p1,16); /*向p1发软中断信号16*/
kill(p2,17); /*向p2发软中断信号17*/
wait(0); /*同步*/
wait(0);
printf("Parent process is killed!\n");
exit(0);
}
else
{
wait_mark=1;
signal(10,stop); /*接收到软中断信号10,转stop*/
waiting();
lockf(stdout,1,0);
printf("<%d> killed by 10!\n",(int)getpid());
lockf(stdout,0,0);
exit(0);
} }
else
{
wait_mark=1;
signal(12,stop); /*接收到软中断信号12,转stop*/
waiting();
lockf(stdout,1,0);
printf("<%d> killed by 12!\n",(int)getpid());
lockf(stdout,0,0);
exit(0);
}
}
void waiting()
{
while(wait_mark!=0);
}
void stop()
{
wait_mark=0;
}