2020-08-14 系统管理员 2022-11-27 08:49 15阅读 0赞 ## GCC编译过程 ## 预处理(.c): 编译,优化(.s, .asm):生成汇编语言 汇编(.o) :汇编过程实际上指把汇编语言代码翻译成目标机器指令的过程。 链接(.exe): 1. 预编译 将.c 文件转化成 .i文件 使用的gcc命令是:gcc –E 对应于预处理命令cpp 2. 编译 将.c/.h文件转换成.s文件 使用的gcc命令是:gcc –S 对应于编译命令 cc –S 3. 汇编 将.s 文件转化成 .o文件 使用的gcc 命令是:gcc –c 对应于汇编命令是 as 4. 链接 将.o文件转化成可执行程序 使用的gcc 命令是: gcc 对应于链接命令是 ld 总结起来编译过程就上面的四个过程:预编译处理(.c) --> 编译、优化程序(.s、.asm)--> 汇编程序(.obj、.o、.a、.ko) --> 链接程序(.exe、.elf、.axf等)。 ## 动态链接与静态链接 ## **静态链接是在形成可执行程序前,而动态链接的进行则是在程序执行时** 链接器在链接静态链接库的时候是以目标文件为单位的。比如我们引用了静态库中的printf()函数,那么链接器就会把库中包含printf()函数的那个目标文件链接进来。 静态链接的缺点很明显,一是**浪费空间**,因为每个可执行程序中对所有需要的目标文件都要有一份副本,所以如果多个程序对同一个目标文件都有依赖,如多个程序中都调用了printf()函数,则这多个程序中都含有printf.o,所以同一个目标文件都在内存存在多个副本;另一方面就是**更新比较困难**,因为每当库函数的代码修改了,这个时候就需要重新进行编译链接形成可执行程序。但是静态链接的优点就是,在**可执行程序中已经具备了所有执行程序所需要的任何东西,在执行的时候运行速度快**。 动态:假设现在有两个程序program1.o和program2.o,这两者共用同一个库lib.o,假设首先运行程序program1,系统首先加载program1.o,当系统发现program1.o中用到了lib.o,即program1.o依赖于lib.o,那么系统接着加载lib.o,如果program1.o和lib.o还依赖于其他目标文件,则依次全部加载到内存中。当program2运行时,同样的加载program2.o,然后发现program2.o依赖于lib.o,但是此时lib.o已经存在于内存中,这个时候就不再进行重新加载,而是将内存中已经存在的lib.o映射到program2的虚拟地址空间中,从而进行链接(这个链接过程和静态链接类似)形成可执行程序。 动态链接的优点显而易见,就是即使需要每个程序都依赖同一个库,但是该库不会像静态链接那样在内存中存在多分,副本,而是这**多个程序在执行时共享同一份副本**;另一个优点是,更新也比较方便,**更新时只需要替换原来的目标文件,而无需将所有的程序再重新链接一遍**。当程序下一次运行时,新版本的目标文件会被自动加载到内存并且链接起来,程序就完成了升级的目标。但是动态链接也是有缺点的,因为把链接推迟到了程序运行时,所以每次执行程序都需要进行链接,所以**性能会有一定损失**。 [传送门][Link 1] ## 线程同步的方法 ## 1.临界区(用户态,只能同一进程内线程的通信) 2.信号量(内核态,可以跨进程间线程同步,不能在分布式操作系统) 3.互斥量(特殊的信号量) 4.事件(通过通知来实现通信同步,可以分布式操作系统) [Link 1]: https://www.cnblogs.com/cyyljw/p/10949660.html
还没有评论,来说两句吧...