文件权限
Linux文件的基本权限就有九个,分别是owner/group/others三种身份各有自己的read/write/execute权限,修改权限指令:chmod。每种身份(owner/group/others)各自的三个权限(r/w/x)分数是需要累加的
软链接和硬链接的区别
软链接又叫符号链接,这个文件包含了另一个文件的路径名。可以是任意文件或目录,可以链接不同文件系统的文件。
硬链接就是一个文件的一个或多个文件名。把文件名和计算机文件系统使用的节点号链接起来。因此我们可以用多个文件名与同一个文件进行链接,这些文件名可以在同一目录或不同目录。
硬链接只能对已存在的文件进行创建,不能交叉文件系统进行硬链接的创建;
软链接可对不存在的文件或目录创建软链接;可交叉文件系统;
硬链接不能对目录进行创建,只可对文件创建;
软链接可对文件或目录创建;
删除一个硬链接文件并不影响其他有相同 inode号的文件。
删除软链接并不影响被指向的文件,但若被指向的原文件被删除,则相关软连接被称为死链接(即 dangling link,若被指向路径文件被重新创建,死链接可恢复为正常的软链接)。
静态库和动态库
gcc hello.c -c //这样就生成hello.o目标文件
ar rcs libhello.a hello.o//生成libhello.a静态库
gcc main.c -lhello -o staticLibrary//main.c和hello静态库链接,生成staticLibrary执行文件
/*
main.c: 是指main主函数
-lhello: 是我们生成的.a 文件砍头去尾(lib不要 .a也不要)前面加-l
-L: 是指告诉gcc编译器先从-L指定的路径去找静态库,默认是从/usr/lib/ 或者 /usr/local/lib/ 去找。
./: 是指当前路径的意思
staticLibrary: 是最后想生成的文件名(这里可随意起名字)
*/
gcc -shared -fpic hello.c -o libhello.so
-shared 指定生成动态库
-fpic :fPIC选项作用于编译阶段,在生成目标文件时就得使用该选项,以生成位置无关的代码。
gcc main.c -lhello -L ./ -o dynamicDepot
/*
main.c: 是指main主函数
-lhello: 是我们生成的.so 文件砍头去尾(lib不要 .so也不要)前面加-l
-L: 是指告诉gcc编译器先从-L指定的路径去找静态库,默认是从/usr/lib/ 或者 /usr/local/lib/ 去找。
./: 是指当前路径的意思
dynamicDepot: 是最后想生成的文件名(这里可随意起名字)
*/
静态库代码装载的速度快,执行速度略比动态库快。
动态库更加节省内存,可执行文件体积比静态库小很多。
静态库是在编译时加载,动态库是在运行时加载。
生成的静态链接库,Windows下以.lib为后缀,Linux下以.a为后缀。生成的动态链接库,Windows下以.dll为后缀,Linux下以.so为后缀。
GDB调试
quit:退出gdb,结束调试
list:查看程序源代码
list 5,10:显示5到10行的代码
list test.c:5, 10: 显示源文件5到10行的代码,在调试多个文件时使用
list get_sum: 显示get_sum函数周围的代码
list test,c get_sum: 显示源文件get_sum函数周围的代码,在调试多个文件时使用
reverse-search:字符串用来从当前行向前查找第一个匹配的字符串
run:程序开始执行
help list/all:查看帮助信息
break:设置断点
break 7:在第七行设置断点
break get_sum:以函数名设置断点
break 行号或者函数名 if 条件:以条件表达式设置断点
watch 条件表达式:条件表达式发生改变时程序就会停下来
next:继续执行下一条语句 ,会把函数当作一条语句执行
step:继续执行下一条语句,会跟踪进入函数,一次一条的执行函数内的代码
条件断点:break if 条件 以条件表达式设置断点
多进程下如何调试:用set follow-fork-mode child 调试子进程或者set follow-fork-mode parent 调试父进程
进程调度算法
操作系统如何管理内存
进程地址空间不隔离。会导致数据被随意修改。
内存使用效率低。
程序运行的地址不确定。操作系统随机为进程分配内存空间,所以程序运行的地址是不确定的。
扩大地址空间。每个进程独占一个4G空间,虽然真实物理内存没那么多。
内存保护:防止不同进程对物理内存的争夺和践踏,可以对特定内存地址提供写保护,防止恶意篡改。
可以实现内存共享,方便进程通信。
可以避免内存碎片,虽然物理内存可能不连续,但映射到虚拟内存上可以连续。
虚拟内存需要额外构建数据结构,占用空间。
虚拟地址到物理地址的转换,增加了执行时间。
页面换入换出耗时。
一页如果只有一部分数据,浪费内存。
linux系统态与用户态
LRU算法及其实现方式
当需要插入新的数据项的时候,如果新数据项在链表中存在(一般称为命中),则把该节点移到链表头部,如果不存在,则新建一个节点,放到链表头部,若缓存满了,则把链表最后一个节点删除即可。
在访问数据的时候,如果数据项在链表中存在,则把该节点移到链表头部,否则返回-1。这样一来在链表尾部的节点就是最近最久未访问的数据项。
linux的栈是通过缺页来分配内存的,不是所有栈地址空间都分配了内存。因此,8M是最大消耗,实际的内存消耗只会略大于实际需要的内存(内部损耗,每个在4k以内)。
页表
操作系统中的缺页中断
缺页异常:malloc和mmap函数在分配内存时只是建立了进程虚拟地址空间,并没有分配虚拟内存对应的物理内存。当进程访问这些没有建立映射关系的虚拟内存时,处理器自动触发一个缺页异常,引发缺页中断。
缺页中断:缺页异常后将产生一个缺页中断,此时操作系统会根据页表中的外存地址在外存中找到所缺的一页,将其调入内存
缺页中断与一般中断一样,需要经历四个步骤:保护CPU现场、分析中断原因、转入缺页中断处理程序、恢复CPU现场,继续执行。
缺页中断与一般中断区别:
在指令执行期间产生和处理缺页中断信号
一条指令在执行期间,可能产生多次缺页中断
缺页中断返回的是执行产生中断的一条指令,而一般中断返回的是执行下一条指令。