操作系统原理实验
环境准备
centOS 7 x64
安装gcc
安装成功!
gnome桌面的所有菜单项都存储如下位置:
/usr/share/applications/
知识栈
程序的编译流程
GCC 编译模式
(1) GCC 支持编译的文件
-
由于 gcc 支持多种语言,因此 gcc 能够支持多种文件后缀的编译。
-
源文件后缀名标识源文件的语言,但是对编译器来说,后缀名控制着缺省设定;
-
gcc:认为预处理后的文件(.i)是 C 文件,并且设定 C 形式的连接。
-
g++:认为预处理后的文件(.i)是 C++文件,并且设定 C++形式的连接。
(2) GCC 编译方式
gcc 指令的一般格式为:gcc [选项] 源文件名 [选项] 目标文件名
根据 gcc 采用命令的不同,可以将 gcc的编译模式分以下三种情况:默认模式、编译模式、编译连接模式。下面通过实例,以理论结合实例的方式,引领读者更好的理解。
a) GCC 编译模式
例 2-1 hello.c 程序
#include <stdio.h>
int main() {
printf("hello world!\n");
return 0;
}
编译模式一:默认方式
采用默认方式编译源文件,系统会生成 a.out 可执行文件,调用 a.out 文件可查看执行结
果,如下图所示。
编译模式二:编译模式
在该模式下,采用“-o”选项,直接将源文件编译成目标文件,如下图:
编译模式三:编译链接模式
在该模式下,采用先编译成目标文件,再编译成可执行文件。首先利用“-c”选项,生成目标文件 hello.o,再利用“-o”选项,生成可执行文件 hello
b)多源文件编译方法
以上 gcc 编译针对一个源文件进行。实际中,一个程序的源代码通常包含在多个源文件之中。因此对于多个源文件,如何用 gcc 处理呢?通常有以下两种方法。
方法一:多个文件一起编译
例 2-1 多文件一起编译
[root@localhost programs]# gcc -o test first.c second.c third.c
说明:该命令将同时编译三个源文件,即 first.c、second.c 和 third.c,然后将它们连接成 一个可执行程序,名为 test。
方法二:分别编译各个源文件,之后对编译后输出的目标文件链接。
例 2-2 多文件编译
[root@localhost programs] #gcc -c first.c //将 first.c 编译成 first.o
[root@localhost programs] #gcc -c second.c //将 second.c 编译成 second.o [root@localhost programs] #gcc -c third.c //将 third.c 编译成 third.o
[root@localhost programs] #gcc -o test first.o second.o third.o //将first.o、second.o 和 third.o 链接成 test
说明
①第一种方法编译时需要所有文件重新编译,而第二种方法可以只重新编译修改的文件,未修改的文件不用重新编译。
②要生成可执行程序时,一个程序无论有有一个源文件还是多个源文件,所有被编译和 连接的源文件中必须有且仅有一个 main 函数,因为 main 函数是该程序的入口点(换句话说, 当系统调用该程序时,首先将控制权授予程序的 main 函数)。但如果仅仅是把源文件编译成 目标文件的时候,因为不会进行链接,所以 main 函数不是必需的。
实验实战
进程管理实验 |
一.实验名称:
进程管理
二.实验目的:
1、 熟悉linux下利用gcc、gdb编译、调试C程序
2、 掌握进程的概念,明确进程的含义
3、 认识并了解并发执行的实质
三.实验准备:
1、 预习linux下利用gcc编译c程序。
2、 参考课件及资料掌握进程的创建过程。
3、 参考课件及资料掌握进程的并发执行。
四.实验内容:
内容一:敲通如下程序,分析运行结果。
#include <stdio.h>
int main()
{
int i;
while((i=fork())==-1); //创建一个子进程,直到创建成功为止
printf("i=%d",i);
if(i)printf("It is a parent process!");
else printf("It is a child process!");
return 0;
}
写出分析结果,程序名字命名为 学号_lab1_1.c,运行结果截图
分析:
-
程序多次的运行结果不同,执行一次程序,i 的值就依次增加,每次增加 2,但后面的字符串不变。
-
执行 while((x=fork())==-1);后,父进程创建一子进程,子进程复制了父进程的资源,成为独立于父进程的一个进程,并且子进程的 fork() 返回值为 0,父进程的 fork() 返回值为刚创建的子进程号。系统先运行子进程,输出 It is a parent process!,进入该分支后,因出现 IO 中断,子进程释放 CPU ,进入阻塞状态,处于就绪状态的父进程得到 CPU 继续执行,进入 else 分支,输出 It is a child process! 。
运行结果
内容二:编写程序,用系统调用fork()创建两子进程。父进程显示50次字符串“father”,子进程1显示50次字符串“son”,子进程2显示50次字符串“daughter”。观察并记录屏幕上显示结果,分析原因。(提示:可在各进程中加入sleep,观察结果分析原因)
写出分析结果,程序名字命名为 学号_lab1_2.c ,运行结果截图
#include<stdio.h>
int main()
{
int i,p1,p2;
while((p1=fork())== -1);
if(p1==0)
for(i=0;i < 10;i++){
printf("son%d\n",i);
}else{
while((p2=fork()) == -1);
if(p2 == 0)
for(i=0;i < 10;i++){
printf("daughter%d\n",i);
}else
for(i=0;i < 10;i++)
printf("father%d\n",i);
}
return 0;
}
分析:
首先执行父程序,如果数值小于 10,则输出 father;执行 10次后, 进入第一个子程序, i 从0开始,输出 10 次son;接着进入第二个子程序, 依次输出 10次 daughter 。
运行结果:
内容三:敲通如下程序,写出运行结果,分析程序功能。
#include <stdio.h>
#include <pthread.h>
void *ptest(void *arg)
{
printf(" This is the new thread!\n" );
return(NULL);
}
int main()
{
pthread_t tid;
printf(" This is the parent process!\n" );
pthread_create(&tid,NULL,ptest,NULL);
sleep(1);
return 0;
}
如果没选修过Linux的C语言编程课程, 那么请自行百度弄清楚Linux下的多线程的gcc编译需要的命令参数 ,写出pthread_create函数用法和程序的执行顺序,写出分析结果,程序名字命名为 学号_lab1_3.c ,运行结果截图。
分析:
进入主程序时输出 “ This is the parent process !”,用创建线程的函数,该函数中主席了指针 ptest 指向的函数,而后输出“ This is the new thread!”返回值为空,程序休眠后结束程序。
运行结果:
注意: 因为 pthread 库不是Linux系统默认的库,连接时需要使用库 libpthread.a ,所以在使用pthread_create创建线程时,在编译中要加上 -pthread 参数
gcc -pthread -o lab1_3 20170xxxx_lab1_3.c