操作系统第一次实验课程
俊超老师的第一次实验课程
Linux环境下gcc的使用以及编程训练
一:gcc条件下在命令行中对c语言的操作
在Linux系统中,可执行文件没有统一的后缀,系统从文件的属性来区分可执行文件和不可执行文件。而gcc则通过后缀来区别输入文件的类别,下面介绍gcc所遵循的部分约定规则。
.c为后缀的文件,C语言源代码文件;
.a为后缀的文件,是由目标文件构成的库文件;
.C,.cc或.cxx 为后缀的文件,是C++源代码文件;
.h为后缀的文件,是程序所包含的头文件;
.i 为后缀的文件,是已经预处理过的C源代码文件;
.m为后缀的文件,是Objective-C源代码文件;
.o为后缀的文件,是编译后的目标文件;
.s为后缀的文件,是汇编语言源代码文件;
.S为后缀的文件,是经过预编译的汇编语言源代码文件
常用编译命令选项
假设源程序文件名为test.c。
- 无选项编译链接
用法:gcc test.c
作用:将test.c预处理、汇编、编译并链接形成可执行文件。这里未指定输出文件,默认输出为a.out。
- 选项 -o
用法:gcc test.c -o test
作用:将test.c预处理、汇编、编译并链接形成可执行文件test。-o选项用来指定输出文件的文件名。
- 选项 -E
用法:gcc -E test.c -o test.i
作用:将test.c预处理输出test.i文件。
- 选项 -S
用法:gcc -S test.i
作用:将预处理输出文件test.i汇编成test.s文件。
- 选项 -c
用法:gcc -c test.s
作用:将汇编输出文件test.s编译输出test.o文件。
- 无选项链接
用法:gcc test.o -o test
作用:将编译输出文件test.o链接成最终可执行文件test。
- 选项-O
用法:gcc -O1 test.c -o test
作用:使用编译优化级别1编译程序。级别为1~3,级别越大优化效果越好,但编译时间越长。
- 生成可执行程序
最简单的生成可执行文件的写法为:
$ cd demo #进入源文件所在的目录
$ gcc main.c #在 gcc 命令后面紧跟源文件名
- 运行可执行程序
上面我们生成了可执行程序,在控制台中输入程序的名字就可以运行,如下所示:
$ ./a.out
./表示当前目录,整条命令的意思是运行当前目录下的 a.out 程序。如果不写./,Linux 会到系统路径下查找
a.out,而系统路径下显然不存在这个程序,所以会运行失败。
将上面两部分的内容连接起来,完整的演示一下从编辑源文件到运行可执行程序的全过程:
$ cd demo #进入源文件所在目录
$ touch main.c #新建空白的源文件
$ gedit main.c #编辑源文件
$ gcc main.c #生成可执行程序
$ ./a.out #运行可执行程序
C语言
$ #继续等待输入其它命令
其次就是学会了脚本的编写。
并行程序的设计,在第一次实验结果基础上,将程序并行化,提高效率。
#include<stdio.h>
#include "read_txt.h"
#include<time.h>
#include<pthread.h>
#include "mystruct.h"
#include "selecting.h"
#include<string.h>
int main(int argc,char * argv[])
{
int i,j,ret;
int num;
int limit;
data_1 d;
pthread_t id;
char order_date[15];
char ship_date[10];
char mktsegment[20];
pthread_t rcus_id,rord_id,ritem_id;
int start_time,end_time;
txt r_txt; //结构体txt内有分别指向 customer,orders和lineitem结构体类型的指针,分别用于指向客户表、订单表和产品表
printf("请输入线程个数:");
scanf ("%d",&(d.num_of_thread));
start_time = clock();
//多线程读取文件
pthread_create(&rcus_id,NULL,read_customer_txt,&r_txt); //创建读取customer.txt的线程,导入客户表
pthread_create(&rord_id,NULL,read_orders_txt,&r_txt); //创建读取orders.txt的线程,导入客户表
pthread_create(&ritem_id,NULL,read_lineitem_txt,&r_txt); //创建读取lineitem.txt的线程,导入客户表
pthread_join(rcus_id,NULL);
pthread_join(rord_id,NULL); //pthread_join的作用在于 阻塞当前进程
pthread_join(ritem_id,NULL); //避免调用进程还没结束就执行下一步导致程序出错
d.r_txt = &r_txt;
num = change_argv_to_number(argv[4]);//总共计算的次数
for(i=0;num>0;num--,i=i+4)
{
strcpy(d.sc1,argv[5+i]);
strcpy(d.sc2,argv[6+i]);
d.sc2[10]=0;
strcpy(d.sc3,argv[7+i]);
limit = change_argv_to_number(argv[8+i]);
ret = pthread_create(&id,NULL,select_final1,&d);
ret = pthread_join(id,NULL);
//printf("ret = %d,main\n");
printf("l_orderkey|o_orderdate|revenue\n");
for(j=0;j<limit;j++)
{
if(d.result[j].l_extendedprice==0)
printf("null |null |null \n");
else
printf("%-10d|%-11s|%-20.2lf\n",d.result[j].l_orderkey,d.result[j].o_orderdate,d.result[j].l_extendedprice);
}
free(d.result);
d.result = NULL;
//printf("print ok ,%d\n",num);
}
//printf("this!ok\n");
end_time = clock();
printf("\n\n查询花费了:%dms\n", end_time-start_time);
return 0;
}
主程序代码