标签:print har 一起 高级 oid com 计算机 使用命令 关系
在linux内核中,比较重要的部分包括系统调用、进程管理、内存管理和文件系统。其中,系统调用就是非内核软件想要使用高级内核功能的一种方法,进程管理是不同任务之间的来回切换,文件系统是硬件资源或者数据资源的一种方式,内存管理是对内存的分配和回收方式。
本文将简要讲解系统调用、进程管理和文件系统的知识,并且分析动态链接对程序性能的影响。
CPU将指令等级分级,目的是为了将系统的核心不能与外部的进程隔离开,保护系统不被糟糕的程序搞得崩溃。也就是说有些指令是需要在高的权限等级才能运行的,而用户程序需要使用这些指令就需要用得到系统调用,本质是把需要执行的指令告诉内核,让内核中的特定代码段来执行这些指令,这些特定的代码段是已经写好了的安全的代码段,所以这种方法是安全的。
内核执行完特定的代码段之后在返回到原来的用户进程。
当然这里还要涉及到,中断的概念。用户进程就是通过触发中断来告诉内核需要进行的代码段。
现代的操作系统大多的面向多任务的。也就是说同一时间内,计算机中会存在多个进程,那么需要怎么管理这些进程呢?
首先我们需要一个数据结构来描述进程的信息,于是我们有了进程描述符。进程描述符中记录了进程运行过程中寄存器内的信息、使用到的资源、状态等信息
然后进程存储在哪里呢?
我们就是用一个双向队列来存储进程吧,这里也要记录进程之间的关系。
进程很多的时候什么进程先运行呢?
这就引入了进程的优先级和调度策略。优先级有0-139,优先级数值越低的优先级越高,Linux内核中有4中常用的调度策略SCHED_NORMAL、SCHED_FIFO 、SCHED_RR和SCHED_BATCH,不同的优先级使用不同的调度策略
当然进程的切换时候的选择是非常复杂的。
计算机中的文件多种多样,存储文件的介质和存储方式多种多样,我们能不能把这些多样的文件统一起来,屏蔽其中的多样性让用户编程简单化。这就是文件系统得目的。
文件系统将文件抽象成文件描述符,对文件得读写操作都可以通过文件描述符实现,即使文件的类型不一样。
进程在没有加载进内存执行的时候称为程序,是存储在外存的一个可执行文件。可执行文件是一种ELF文件。
在C语言的世界里,编辑好的代码是源文件(单纯的文本文件)。源文件变成一个可执行文件需要经过以下几个步骤:
两个概念:
链接的时候直接将需要的代码拼接带最终的可执行文件中。生成的可执行文件ELF内部不存在找不到的函数。
编译时不直接复制可执行代码,而是通过记录一系列符号和参数,在程序运行或加载时将这些信息传递给操作系统。
操作系统将需要的动态库加载到内存中, 然后程序在运行到指定的代码时, 去共享执行内存中已经加载的动态库。
动态链接分为:
dlopen()
函数来加载共享库,就像加载文件一样,然后通过dlsym()
函数和符号来找到需要的函数。首先准备一个testlib.c和testlib.h
// testlib.c
#include "testlib.h"
int add(int a,int b) {
return a + b;
}
//testlib.h
#ifndef _DL_LIB_EXAMPLE_H_
#define _DL_LIB_EXAMPLE_H_
#ifdef __cplusplus
extern "C" {
#endif
int add(int a,int b);
#ifdef __cplusplus
}
#endif
#endif /* _DL_LIB_EXAMPLE_H_ */
使用命令gcc -shared testlib.c -o libtestlib.so
将编译出动态链接库
使用程序teststatic.c如下:
#include <stdio.h>
#include "testlib.h"
int main() {
long a = 0,i = 0;
for (i = 0;i < 1e10;i++) {
a += add(i,-i + 100);
}
printf("%ld\n",a);
return 0;
}
使用命令gcc teststatic.c testlib.c -o teststatic -static
编译出静态链接的可执行文件
然后使用time ./teststatic
查看程序的运行时间
这部分的代码与静态链接的相同,但是编译的命令不同。
源文件名为testloadlink.c
使用命令gcc testloadlink.c -o testloadlink -L"/home/liuyong/linux_study/final" -l"testlib"
编译。
然后使用命令export LD_LIBRARY_PATH=$PWD
将当前目录添加到动态链接库可查找的目录中。
使用time ./testloadlink
查看程序运行时间
源文件代码
#include <stdio.h>
#include <dlfcn.h>
int main() {
void * handle = dlopen("testlib.so",RTLD_NOW);
int (*add)(int,int);
add = dlsym(handle,"add");
long a = 0,i = 0;
for (i = 0;i < 1e10;i++) {
a += add(i,-i + 100);
}
printf("%ld\n",a);
return 0;
}
使用命令gcc testruntimelink.c -o testruntimelink -L"/home/liuyong/linux_study/final" -l"testlib" -ldl
编译
然后运行得到用时
通过多次的运行测试,可以发现静态链接的运行时间普遍在20s左右,而装载时链接会在22s左右,运行时链接在21s左右。静态链接比动态链接速度快。
但是静态链接的可执行文件大小比动态链接大很多
一开始以为静态链接会导致内联优化,但是开始-o2优化级别后静态链接的时间还是20s左右。所以还是按照常规的解释
静态链接不需要在内存中查找共享库的位置,代码跳转在程序自己的段空间中速度会快很多
而动态链接在运行到需要链接的函数时会去查找内存中的动态库,速度就慢了
标签:print har 一起 高级 oid com 计算机 使用命令 关系
原文地址:https://www.cnblogs.com/ly-yong/p/14778379.html