这次的应该是学校自添的,没有文章辅助了,尝试纯自己动脑。
实验准备:
学习ps、pstree和kill等命令的使用方法。能通过ps命令查看进程号、可执行文件名(命令)、运行状态信息;能通过pstree查看系统进程树;能利用kill命令根据进程号(pid)杀死进程。
在主目录创建姓名-学号文件夹,并在该文件夹创建lab6文件,编写以下代码并保存为1.c。(该代码产生两个进程,并且通过getchar()进行阻塞)
代码在文档中已给出:
#include<stdio.h>
#include<unistd.h>
int main()
{
pid_t pid=fork();
if(pid<0)
printf("error!");
else if(pid==0)
getchar();
else
getchar();
return 0;
}
按照步骤创建文件然后粘贴代码。在终端中运行:
gcc 1.c -o hello
./hello &
&表示后台执行,运行后会出现父进程pid
得到:[1] 2725
输入:ps
得到:
PID TTY TIME CMD
2703 pts/0 00:00:00 bash
2725 pts/0 00:00:00 hello
2726 pts/0 00:00:00 hello
2731 pts/0 00:00:00 ps
[1]+ 已停止 ./hello
输入:pstree -p 2725(这里的2725是上面得到的pid数字)
得到:hello(2725)───hello(2726)
输入:kill -kill 2725
得到:[1]+ 已杀死 ./hello
再次输入:ps
得到:
PID TTY TIME CMD
2703 pts/0 00:00:00 bash
2772 pts/0 00:00:00 ps
在lab6文件夹里面编写代码,创建6个子进程,并保存为2.c。这次仍旧有代码参考:
#include<stdio.h>
#include<unistd.h>
#include <sys/types.h>
int main()
{
for(int i=0;i<6;i++)
{
pid_t pid =fork();
if(pid<0) printf("error!");
if(pid==0) break;
if(pid>0) continue;
}
getchar();
return 0;
}
输入指令安装vim:(安装过程中有Y/N选项,内存够,点回车就好)
sudo apt-get install vim
输入:vim 2.c
得到:
输入: gcc 2.c -o 2.1
错误提示:
2.c: In function ‘main’:
2.c:5:2: error: ‘for’ loop initial declarations are only allowed in C99 mode
for(int i=0;i<6;i++)
^
2.c:5:2: note: use option -std=c99 or -std=gnu99 to compile your code(这里提示加上-std=c99)
重新输入指令:
gcc 2.c -std=c99 -o 2.1
./2.1 &
得到:[1] 3794
输入:pstree -p 3794
得到:
2.1(3794)─┬─2.1(3795)
├─2.1(3796)
├─2.1(3797)
├─2.1(3798)
├─2.1(3799)
└─2.1(3800)
[1]+ 已停止 ./2.1
编写3.c,实现6层子进程嵌套(使用getchar作为阻塞,子进程会被kill且ps只能显示2个进程,此处选用pause阻塞) 到这里就没有代码参考了,所以大家接下来可能会看到很烂的代码。
使用递归方式创建6层子进程嵌套。create
函数负责创建子进程并递归调用自身,直到达到指定的层数。当递归到最底层时,子进程将调用 pause
阻塞自己并退出。
主进程在调用 create
函数后等待子进程结束,最后返回。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
void create(int n) {
if (n == 0) {
pause();
exit(0);
}
pid_t pid = fork();
if (pid == 0) {
create(n - 1);
}
if (pid > 0) {
wait(NULL);
exit(0);
} else {
printf("Errord!");
exit(1);
}
}
int main() {
create(6);
return 0;
}
输入指令:
vim 3.c
gcc 3.c -std=c99 -o 2.2
./2.2 &
ps
pstree -p [pid]
编写4.c,实现一个父进程下面3个子进程,一个子进程下面3个进程。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
for(int i=0;i<3;i++)
{
pid_t pid =fork();
if(pid<0) printf("error!");
if(pid==0)
{
for(int j=0;j<3;j++)
{
pid_t pid=fork();
if(pid<0) printf("error!");
if(pid==0) break;
if(pid>0) continue;
}
break;
}
if(pid>0) continue;
}
pause();
return 0;
}
gcc 4.c -std=c99 -o 2.3
./2.3 &
pstree -p [pid]
编写5.c,实现父进程与子进程交替输出10次,父进程输出word pid,子进程输出 hello pid。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
pid_t pid = fork();
for (int i = 0; i < 10; i++)
{
if (pid == 0)
{
printf("hello %d\n", getpid());
pid = getppid(); // 获取父进程的 PID
}
else if (pid > 0)
{
printf("world %d\n", getpid());
pid = 0; // 将 pid 置为 0,表示当前进程是父进程
}
}
return 0;
}
自定义shell
尝试自行设计一个C语言小程序,完成基本的shell功能
要求:给出命令行提示符,能够逐次接收命令;对于命令分三种,内部命令(实现help命令给出用法,exit命令退出shell,xuehao命令输出自己自己的学号)、外部命令(磁盘上的可执行文件)以及无效命令(不是上述2种命令)。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
void execute_internal_command(char* command);
void execute_external_command(char* command);
int main()
{
char command[100];
while (1)
{
printf("shell> ");
fgets(command, sizeof(command), stdin);
// 删除换行符
command[strcspn(command, "\n")] = '\0';
if (strcmp(command, "help") == 0)
{
printf("This is a simple shell program.\n");
printf("Commands:\n");
printf("help - Display this help message\n");
printf("exit - Exit the shell\n");
printf("xuehao - Output your student ID\n");
}
else if (strcmp(command, "exit") == 0)
{
break;
}
else if (strcmp(command, "xuehao") == 0)
{
printf("Your student ID is xxxxxxxx\n");
}
else
{
pid_t pid = fork();
if (pid < 0)
{
fprintf(stderr, "Fork failed\n");
exit(1);
}
else if (pid == 0)
{
execute_external_command(command);
exit(0);
}
else
{
wait(NULL);
}
}
}
return 0;
}
void execute_internal_command(char* command)
{
if (strcmp(command, "help") == 0)
{
printf("This is a simple shell program.\n");
printf("Commands:\n");
printf("help - Display this help message\n");
printf("exit - Exit the shell\n");
printf("xuehao - Output your student ID\n");
}
else if (strcmp(command, "exit") == 0)
{
exit(0);
}
else if (strcmp(command, "xuehao") == 0)
{
printf("Your student ID is xxxxxxxx\n");
}
}
void execute_external_command(char* command)
{
char* arguments[10];
int num_arguments = 0;
// 解析命令行参数
char* token = strtok(command, " ");
while (token != NULL && num_arguments < 10 - 1)
{
arguments[num_arguments] = token;
num_arguments++;
token = strtok(NULL, " ");
}
arguments[num_arguments] = NULL;
execvp(arguments[0], arguments);
// 如果 execvp 失败,则打印错误信息并退出子进程
fprintf(stderr, "Command not found: %s\n", arguments[0]);
exit(1);
}