OS-Lab2-Linux进程控制相关命令和系统调用(含gcc编程)

arm's blog / 2024-10-21 / 原文

实验目的
1) 概念:Linux的gcc编译器
2) 演示/实践:gcc编译器的初步和入门(编写一个带printf的while程序)
3) 演示/实践:Linux进程控制相关的命令(如ps/pstree/top/kill/等)演示/实践:Linux进程控制相关的系统调用(如fork()/getpid()等)
4) 概念:Linux的gdb调试器
5) 概念:Linux的make工具及其Makefile
6) 演示/实践:make工具及其Makefile的初步和入门(多个c/h文件构成的一个C项目:但是存在bug);进而用gdb调试器来调试和分析此bug
实验步骤:
Task1: gcc编译器的初步和入门:利用vi/vim编辑器,输入以下程序while.c的代码,然后利用gcc编译器进行编译、链接,和运行




Task2: Linux进程控制相关的命令:利用top/ kill/ps/htop/等的命令,要求完成的步骤如下描述。
1.输入top观察当前进程状态:

2.运行以上lab1的while程序,再次执行top命令,然后观察新的、当前的进程状态

3. 等待while程序执行完成正常结束后,进程消失

4. 重新执行while程序,并使用kill结束程序,top中进程消失


5. 使用htop命令

Task3: Linux进程控制相关的系统调用(如fork()/getpid()等):通过process.c程序来理解Linux进程创建的过程和特点(如父子进程的关系、“一次调用和两次返回”的特点)。具体过程包括:利用vi/vim编辑器,输入以下程序process.c的代码,然后利用gcc编译器进行编译、链接,和运行




Task4: make工具及其Makefile的初步和入门,gdb调试器的初步和入门:利用vi/vim编辑器,编写一个由多个文件(如.c和.h)构成的程序,通过Makefile文件来使用make,从而完成本程序的编译和链接过程,然后利用gcc编译器进行编译、链接和运行,观察其存在的bug,然后利用gdb调试器分析和解决这个bug。

点击查看代码
/*main.c*/
#include "mytool1.h"
#include "mytool2.h"
int main()
{
	mytool1_print("hello mytool1!");
	mytool2_print("hello mytool2!");
	return 0;
}
/*mytool1.c*/
#include "mytool1.h"
#include <stdio.h>
void mytool1_print(char *print_str)
{
	printf("This is mytool1 print : %s ",print_str);
}
/*mytool1.h*/
#ifndef _MYTOOL_1_H
#define _MYTOOL_1_H
	void mytool1_print(char *print_str);
#endif
/*mytool2.c*/
#include "mytool2.h"
#include <stdio.h>
void mytool2_print(char *string)
{
	char * string2;
	int size,i;
    size = strlen(string1);
	 string2 =(char*)malloc(size+1);
    for(i=0;i<size;i++)
       string2[size-i]=string1[i];
    string2[size+1]=‘\0’;
    printf(“the changed string is %s\n ”,string2);
}
/*mytool2.h*/
#ifndef _MYTOOL_2_H
#define _MYTOOL_2_H
	void mytool2_print(char *print_str);
#endif

![](https://img2024.cnblogs.com/blog/3538560/202410/3538560-20241016140001172-2123688265.png) 根据编译过程中的报错添加string1的定义,修改mytool2.c为如下: ![](https://img2024.cnblogs.com/blog/3538560/202410/3538560-20241016140047261-1296576162.png) 修改之后继续执行make此时发现执行成功 ![](https://img2024.cnblogs.com/blog/3538560/202410/3538560-20241016140124153-603876030.png) 然后进行gcc编译、链接、运行代码: ![](https://img2024.cnblogs.com/blog/3538560/202410/3538560-20241016140757691-1177487262.png) 运行时发现语句输出不全,故使用gdb对其进行调试,然后发现应该是mytool2.c的问题: ![](https://img2024.cnblogs.com/blog/3538560/202410/3538560-20241016140822745-1861613314.png) 对mytool2.c进行调试,然后发现应该是循环体出问题: ![](https://img2024.cnblogs.com/blog/3538560/202410/3538560-20241016140859324-1094517684.png) 然后进入代码进行修改,如下,具体修改了size-i与size+1: ![](https://img2024.cnblogs.com/blog/3538560/202410/3538560-20241016140928102-2123014239.png) 输出得到正确输出: ![](https://img2024.cnblogs.com/blog/3538560/202410/3538560-20241016140950705-837348803.png) **Task5** 请用自己的语言(当然,也可结合辅助的图),谈谈你对Linux的fork()系统调用的“一次调用和两次返回”这个特点的理解: Linux 中的 fork() 系统调用是用于创建一个新的进程的函数,它会在当前进程的基础上复制一个完全相同的子进程,并且在父进程和子进程中都会返回。这样,fork() 调用一开始似乎只有一次返回,但实际上会在两个进程中各返回一次,形成了“一次调用,两次返回”的特点。