《计算机系统II》自主项目三笔记

这次的应该是学校自添的,没有文章辅助了,尝试纯自己动脑。

实验准备:

学习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);
}

  • 28
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值