l 熟悉Linux操作系统在命令行的基本操作
l 掌握在Linux下C程序的编辑、编译、调试的基本方法:
n 掌握VIM的基本操作及在Vim中C源程序的编辑技巧
n 掌握使用gcc编译器进行C程序编译的基本方法和技巧
n 掌握使用gdb进行调试的基本方法与技巧
l 硬件
n 主机:Pentium III以上;
n 内存:128MB以上;
n 显示器:VGA或更高;
n 硬盘空间:至少100MB以上剩余空间。
l 软件
Linux操作系统,内核2.4.26以上,预装有X-Window、vim、gcc、gdb和任意web浏览器。
阅读与Linux操作、vi使用、gcc和gdb有关的参考资料,理解以下内容:
1. Linux命令行界面与图形界面有何不同;
2. vi的功能和操作特点;
3. gcc的功能和特色;
4. gdb的功能和操作特点;
5. vi、gcc和gdb组合后的功能
通过一个Linux下的应用程序安装示例,学习部分Shell的基本操作命令,主要包括:
1. 系统的启动与关闭
2. 系统登录
3. 目录管理
4. 文件管理、
5. 压缩与解压缩
vimtutor是vi自带的一个入门教程,它直接在vi的真实环境下一步步地教授vi的基本操作命令。它有多种语言版本,通过命令行参数选择不同的语言。执行“vimtutor zh”进入简体中文教程,有些发行商的版本缺省语言就是简体中文,直接运行vimtutor即可。
我们将学习vimtutor中的前五讲,内容包括:
1. 新文件、编辑旧文件、保存和退出;
2. 光标移动、文本编辑之删除、插入、替换、更改;
3. 对象的概念和撤销操作;
4. 复制和粘贴;
5. 定位和搜索;
6. 执行外部命令的方法。
阅读由陈皓编写的教程《用GDB调试程序》,用vi建立示例程序,按其中的步骤操作,学习如下内容:
1. 用gcc编译器编译可执行文件和附带调试信息的方法;
2. 用gdb跟踪调试程序的基本命令,包括查看源代码、设断点、查看变量值、查看函数堆栈、单步运行和连续运行等。
回答下列问题,写入实验报告。
1. 你认为命令行界面和图形界面各有什么优缺点?你更喜欢哪种界面?为什么?
2. 如果要执行当前目录下的configure文件,应该输入什么命令?
3. vi中一次删除一行、一词和一个字符的命令分别是什么?
4. 如果用gdb调试未加入调试信息的目标代码会出现什么现象?
5. gcc和gdb都属于一个叫做GNU的组织。这个组织的全称是什么?它有什么特色?
l 通过观察、分析实验现象,深入理解进程及进程在调度执行和内存空间等方面的特点
l 掌握在POSIX规范中fork和kill系统调用的功能和使用
1. 硬件
(1) 主机:Pentium III以上;
(2) 内存:128MB以上;
(3) 显示器:VGA或更高;
(4) 硬盘空间:至少100MB以上剩余空间。
2. 软件
Linux操作系统,内核2.4.26以上,预装有X-Window、vi、gcc、gdb和任意web浏览器。
学习man命令的用法,通过它查看fork和kill系统调用的在线帮助,并阅读参考资料,学会fork与kill的用法。
复习C语言的相关内容。
通读下列代码:
/*
* POSIX下进程控制的实验程序残缺版 1.2
* 作者:Sunner Sun
* 最后修改时间:2005-3-10 23:59
*/
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <ctype.h>
/* 允许建立的子进程个数最大值 */
#define MAX_CHILD_NUMBER 10
/* 子进程睡眠时间 */
#define SLEEP_INTERVAL 2
int proc_number=0; /* 子进程的自编号,从0开始 */
void do_something();
main(int argc, char* argv[])
{
int child_proc_number = MAX_CHILD_NUMBER; /* 子进程个数 */
int i, ch;
pid_t child_pid;
pid_t pid[10]={0}; /* 存放每个子进程的id */
if (argc > 1)
{
/* 命令行参数中的第一个参数表示建立几个子进程,最多10个 */
child_proc_number = atoi(argv[1]);
child_proc_number
= (child_proc_number > 10) ? 10 : child_proc_number;
}
for (i=0; i<child_proc_number; i++)
{
/* 在这里填写代码,建立child_proc_number个子进程
* 子进程要执行
* proc_number = i;
* do_something();
* 父进程把子进程的id保存到pid[i] */
}
/* 让用户选择杀死哪个进程。输入数字(自编号)表示杀死该进程
* 输入q退出 */
while ((ch = getchar()) != 'q')
{
if (isdigit(ch))
{
/* 在这里填写代码,向pid[ch-'0']发信号SIGTERM,
* 杀死该子进程 */
}
}
/* 在这里填写代码,杀死本组的所有进程 */
return;
}
void do_something()
{
for(;;)
{
/* 打印子进程自编号。为清晰,在每个号码前加“号码+3”个空格
* 比如号码是1,就打印" 1" */
printf("This is process No.%*d\n",
proc_number+3,
proc_number);
sleep(2); /* 主动阻塞两秒钟 */
}
}
先猜想一下这个程序的运行结果。假如运行“./process 20”,输出会是什么样?
然后按照注释里的要求把代码补充完整,运行程序。可以多运行一会儿,并在此期间启动、关闭一些其它进程,看process的输出结果有什么特点,记录下这个结果。
开另一个终端窗口,运行“ps aux|grep process”命令,看看process究竟启动了多少个进程。
回到程序执行窗口,按“数字键+回车”尝试杀掉一两个进程,再到另一个窗口看进程状况。
按q退出程序再看进程情况。
回答下列问题,写入实验报告。
1. 你最初认为运行结果会怎么样?
2. 实际的结果什么样?有什么特点?试对产生该现象的原因进行分析。
3. proc_number这个全局变量在各个子进程里的值相同吗?为什么?
4. kill命令在程序中使用了几次?每次的作用是什么?执行后的现象是什么?
5. 使用kill命令可以在进程的外部杀死进程。进程怎样能主动退出?这两种退出方式哪种更好一些?
6. 把你的程序源代码附到实验报告后。