程序员的自我修养

直接将应用程序运行在物理内存上存在的问题:
1、 地址空间不隔离
2、 内存使用效率低
3、 程序运行地址不确定

MMU(内存管理单元)将虚拟内存映射到物理内存上

线程调度:不断在处理器上切换不同线程的行为称为线程调度
线程同样拥有至少三种状态:
运行
就绪
等待
处于运行中线程拥有一段可以执行的时间,这段时间称为时间片(Time Slice),当时间片用尽的时候,该进程将进入就绪状态。

Windows中原子操作的API
InterlockedExchange //原子地交换两个值
InterlockedDecrement //原子地减少一个值
InterlockedIncrement //原子地增加一个值
InterlockedXor //原子地进行异或操作

CPU乱序可能引发的问题:
单例模式中的双检锁

Volatile T* pInst = null;
T* GetInstance()
{
	If(pInst == null)
    {
	    Lock();
        If(pInst == NULL)
        {
            pInst = new T;
        }
	    unlock();
    }
    return pInst;
}

这样的代码,抛开逻辑是完全没有问题的,但实际上存在隐藏问题,问题的来源就是CPU的乱序执行导致的
C++里的new包含两个步骤:
1) 分配内存
2) 调用构造函数
所以这里的pInst = new T;包含了三个步骤
1) 分配内存
2) 在内存的位置上调用构造函数
3) 将内存的地址赋值给pInst
在这三个步骤中2和3是可以颠倒的。也就是说pInst已经分配好内存了,并且也赋值给了pInst,但是这个时候构造函数还没有执行完毕,就有另一个线程调用了,这时就会返回到构造函数没有执行完毕的pInst对象以提供给用户使用。这时候程序会不会崩溃就取决于这个类的设计如何了。
为了解决这个问题,可以使用CPU提供的一条指令,barrier()

Volatile T* pInst = null;
T* GetInstance()
{
	If(pInst == null)
    {
	    Lock();
        If(pInst == NULL)
        {
            T* pTemp = new T;
            Barrier()
            pInst = pTemp;
        }
	    unlock();
    }
    return pInst;
}

由于barrier的存在,对象的构造一定在barrier执行之前完成,因为当pInst被赋值时,返回的对象总是已经构造完成的。

预编译:
gcc -E hello.c -o hello.i
编译
gcc -S hello.i -o hello.s
汇编
gcc -c hello.s -o hello.o

在预编译阶段做了什么?
1、处理所有的预编译指令 #if #elif #else #endif #define #include
2、删除所有的注释
3、添加行号和文件名标识,以便与编译器能够提示错误或者警告的行号
4、保留所有的#pragma编译器指令

编译器过程就是把预处理完的文件进行一系列语法分析、语义分析及优化后生产相应的汇编代码文件。
汇编器是把汇编代码转换成机器之一执行的指令,每一个汇编语句几乎都对应一条机器指令。
编译器做了什么?
最直接的描述编译器就是将高级语言最终翻译成机器语言的一个工具。
编译过程一般可以分为6步:
扫描、语法分析、语义分析、源代码优化、代码生成、目标代码优化

扫描器
语法分析器:对扫描器产生的记号进行语法分析,产生语法树
语义分析器
源码级优化器

链接过程:

模块间依靠符号来通信类似于拼图版,定义符号的模块多出一块区域,引用该符号的模块刚好少了那一块区域,两者一拼接,刚好完美组合。这个模块的拼接过程就是链接(Linking)
模块间拼接
静态链接过程就是将每个模块的源代码文件经过编译器编译成目标文件(object File一般扩展名为.o或.obj),目标文件和库(Library)一起链接形成最终可执行文件。
库其实就是一组目标文件的包,就是一些最常用的代码编译成目标文件后打包存放。

编译后的目标文件

编译器编译源代码后生成的文件叫做目标文件。目标文件从结构上讲,它是已经编译后的可执行文件格式,只是还没有经过链接的过程,其中可能有些符号或有些地址还没有被调整。其实它本身就是按照可执行文件格式存储的,只是跟真正的可执行文件在结构上稍有不同。
目标文件的格式:
windows下的PE(Portable Executable)
linux下的ELF(Executable Linkable Format)
目标文件就是源代码编译后但未进行链接的那些中间文件(windows的.obj和Linux下的.o),它跟可执行文件的内容与结构很相似,所以一般跟可执行文件格式一起采用一种格式存储。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值