Interface的概念:计算机中,每个层次之间的通信协议(这里的接口区别于Java等编程语言的接口)。

内存管理

内存的分段管理:
基本思路是把一段与程序所需要的内存空间大小的虚拟空间映射到某个地址空间。给出一个示例图:

但是分段存在一个效率问题,比如我们的硬盘是100M,此时由10M、80M和30M三个程序,不论怎样分段,都无法完成高效的映射。

内存的分页管理:
分页的基本思路是把内存的地址空间人为的分成固定大小的页,操作程序可以有部分在内存中,有部分在磁盘中。根据程序利用的“二八法则”,可以灵活地调整内存分配。

线程、进程与并发

进程拥有独立的地址空间,资源对外封闭,是操作系统调度的单位。线程是CPU执行的单位,是轻量级的继承,有自己的寄存器集合和堆栈,但是资源不封闭。

线程或者进程会有不同的状态,基本的状态转化图:

Linux与windows相比,创建进程消耗的资源更少,可以快速创建大量的进程,创建方式有三种,分别是:

  • fork:复制当前进程
  • exec:使用新的可执行映像覆盖当前可执行映像
  • clone:创建子进程并从指定位置开始执行

fork的速度非常快,fork本身不会立刻复制原来任务的内存空间,而是和原来的任务共享写时复制的内存空间。写时复制是指两个任务可以同时自由读取内存,如果任意一个任务对内存空间进行写的操作,那么内存就会复制一份给修改方单独使用。

fork只能产生本任务的镜像,我们可以先fork一个进程,然后调用exec函数来执行一个新的任务,从而达到多进程执行不同任务的目的。

锁、互斥量和信号量的概念:

  • 锁:锁是一个概念,是为了保护某个代码段只能同时被一个线程所访问,这个代码段成为临界区。
  • 信号量:访问信号量的值小于0时,线程进入等待状态;在访问资源完成后,信号量的值加1,如果此时信号量的小于1,则唤醒一个等待的线程。二元信号量是最简单的锁的结构。信号量可以被任何的线程释放!!!
  • 互斥量mutex:资源仅仅允许一个线程访问,但是互斥量只能被获取互斥量的线程释放。

可重入函数:在函数调用结束前,如果有其他的线程调用该函数,函数产生的结果不会发生变化。可重入函数是并发执行的保障。

编译器的过度优化和volatile关键字

首先要明白,线程拥有各自独立的寄存器,线程在读取变量的时候,会先从内存获取数据添加到自己的寄存器中,然后在寄存器中操作完毕后放回内存中。第一个过度优化的情况是,编译器为了提高程序速度,在寄存器操作完后,不把数据立刻放回内存中,而可能过一段时间才放回内存;第二个过度优化是,编译器可能把看似逻辑上不相关的操作指令调换顺序。

第一个操作带来的问题:

x = 0;
Thread1    Thread2
lock();    lock();
x++;       x++;
unlock();  unlock();

虽然加锁了,但是程序执行自增操作后,此时某个线程离开了临界区,为了优化速度不把寄存器的x立刻放回内存,那么另一个程序操作的数据是没有更新的,这样就是造成数据错误。

第二个操作带来的问题:

x = y = 0;
Thread1    Tread2
x = 1;     y = 1;
r1 = y;    r2 = x;

编译器为了优化速度,可能把看似不相关的程序调换下位置,比如x = 1r1 = y的顺序被调换了,那么r1r2就会出现同时为0的情况。

volatile指令可以做两件事情:

  • 阻止编译器为了提高速度把一个变量缓存到寄存器而不写回内存
  • 阻止编译器调整volatile变量的指令顺序

但是,volatile无法阻止CPU动态调度换序,因此还是存在并发的问题

程序员自我修养笔记1相关推荐

  1. 程序员自我修养笔记:第九章

    第九章 Windows下的动态链接 1.相当于Linux下的共享库,Window系统大量采用dll机制,dll更加强调模块化,经常可以看到Windows平台大量的大型软件都通过升级dll的形式自我完善 ...

  2. Linux下main函数启动过程【程序员自我修养笔记】【自用】

    1. 入口函数和程序初始化 1.1 程序从main开始吗? 当程序执行到main函数的第一行时,很多事情都已经完成了: [证1]如下是一段C语言代码: 代码中可以看到,在程序刚刚执行到main的时候, ...

  3. 程序员自我修养笔记:第八章

    第八章:Linux共享库的组织 1.共享库版本不同,可能引起ABI发生变化,从而影响程序的正常运行.因此各个系统会有自己的一套共享库版本命名规则.Linux的为 libname.so.x.y.z x: ...

  4. 程序员自我修养笔记:第12章

    第 12章 系统调用原理 1.普通应用程序运行在用户态下,唯一进入内核态的方式就是通过系统中断.中断分硬件中断和软件中断,软件中断一般以int 0x80号进入系统中断处理程序.中断号很好,因此一般中断 ...

  5. 《程序员自我修养》第七章读书笔记

    书还是接上回,本篇主要对第七章的相关内容进行总结.第七章主要对动态链接的相关内容进行分析. 7.1 为什么要动态链接 既然要对动态链接进行分析,首先应对动态链接出现的原因进行一个简单的分析.动态链接从 ...

  6. 程序员自我修养之链接

    我最近在看PE文件,稍后可能需要dll这些所以顺带看看链接.太久不看这些书,你问我链接是干什么的,我可能会说就是分模块时候用啊,因为一个项目有很多模块,不能写在同一个文件下,所以要把它们链接起来,链接 ...

  7. 程序员自我修养》系统调用与API

    什么是系统调用 在现代的操作系统里,程序运行的时候,本身是没有权利访问多少系统资源的.由于系统有限的资源有可能被多个不同的应用程序同时访问,因此,如果不加以保护,那么各个应用程序难免产生冲突.所以现代 ...

  8. 一个Java工程师的自我修养_程序员自我修养

    毕业N年,每个人在能力跑道上,有了或大或小的差距.有些人一直在重复的劳动,有些人却能从中总结和解决问题.通过成长日活动,我们或许可以探讨下,怎样共同成长.共同前行,跟"勤奋战术掩盖下的战略懒 ...

  9. 程序员自我修养阅读笔记——运行库

    主要关注程序的启动过程. 1 入口函数和程序初始化 1.1 程序真正的入口   通常写代码时,我们认为程序的入口是main函数,但是实际上有一些现象值得我们怀疑该结论是不是正确的.比如全局变量的初始化 ...

最新文章

  1. Android性能优化典范笔记(1)-GPU绘制性能优化
  2. c语言全局变量和局部变量作用域重合时,c语言全局变量与局部变量(当变量重名时)的使用情况...
  3. c++ 智能指针用法详解
  4. c++opencv显示中文_OpenCV如何入门秘籍
  5. postman使用指南
  6. 关于Servlet出现乱码问题
  7. think php 3.2.3 环境,ThinkPHP 3.2.3 入口文件配置
  8. p8b75-m修改bios文件_傻瓜式方法:VMWARE使用NAT方式彻底解决开发板无法挂载ubuntu文件的难题...
  9. 下载sqlserver2012 试用_大肥虫助手app下载-大肥虫助手最新版本下载v7.0.4
  10. 实对称矩阵可对角化证明
  11. 半导体器件制造封装材料和生产工艺流程(图文介绍)
  12. 使用augpush实现微信内跳转浏览器下载APP(包括apk和ios)的解决方案
  13. SPSS Modeler泰坦尼克号幸存者分析
  14. 【Leetcode】每日一题2021/09/08
  15. CSS画卡通人物:皮卡丘
  16. Oracle 常见错误总结及问题解决方法
  17. [工具]-WIKI/文档编写相关软件
  18. 容器化 Spring Boot 代码的 9 个技巧
  19. python group() 和 groups()的区别
  20. centos 64位linux系统下安装appt(只有32位)命令的apktool工具包的笔记

热门文章

  1. 记一次微信数据库解密过程
  2. 实验2.3 使用重载函数模板重新实现上小题中的函数Max1
  3. 买表(【CCF】NOI Online能力测试3 入门组)
  4. 目标检测——对数据进行EDA分析的学习笔记
  5. Youki的Matlab命名规则
  6. 使用MOE进行药效团建模与分析
  7. SpringMVC中的Controller默认单例
  8. CSDN写博客时设置图片显示大小
  9. 【人生】比未知更可怕的是预知---献给那些毕业季的童鞋
  10. 【Linux】Ubuntu 代理配置