zoukankan      html  css  js  c++  java
  • 读书笔记:程序员的自我修养-----第一章(综述)

    题前:30--45天读完,一周至少3篇读书笔记。不能坚持,不再联系,不再找你。

    一. hello world 程序引出的问题,看40天后,再回来看看自己的答案,提升多少。

      Q1:程序为什么要被编译器编译之后才可以运行?

         A1 : 系统执行的机器语言,即二进制文件,程序是文本文件需要编译之后,由链接器链接需要的基本库生成二进制文件.

           Q2: 编译器在把C语言程序转换成可以执行的机器码的过程中作了什么,怎么做的?

        A2: 预处理,汇编器生成汇编文件,编译器生成目标文件,链接器链接生成可执行文件

        Q3: 最后编译的可执行文件里是什么?除了机器码还有什么?它们怎么存放的,怎么组织的?

      A3: 可执行文件里面是机器码,除了机器码还有什么?   未知。 组织: bss,data, code,这个遗忘了

      Q4: #include<stdio.h>是什么意思? 把stdio.h包含进来意味着什么?C语言库又是什么?它是怎么实现的?

      A4: 在预处理时,会把stdio.h头文件里的程序语句加到源文件里。把stdio.h包含进来意味着可以使用在stdio.h里声明的库函数。

          C语言库是为了方便程序员,而提供的基本的诸如I/O,字符处理的库函数. 怎么实现?通过动态或静态编译实现的.不知对否.

      Q5: 不同的编译器和不同的硬件平台以及不同的操作系统,最后编译的结果一样吗?为什么?

      A5: 不同的编译器因为处理(具体什么处理,不清楚)不同,所以接过不一样;不同的硬件平台因为指令结构不同,处理接过也不一样;

            不同的操作系统因为二进制格式不一样,所以编译出来的接过不一样.

      Q6: Hello World是怎么运行起来的?操作系统是怎么装载它的?它从哪儿开始执行,到那儿结束?main函数之前发生了什么?main函数结束以后发生什么?

           A6: 操作系统加载到内存,找到程序入口地址,开始运行;怎么装载,未知;起于何处,至于何处未知?main函数前后发生什么未知.

      Q7: 如果没有操作系统, Hello World可以运行吗?如果要在一台没有操作系统的机器上运行Hello World需要什么?应该怎么实现?

      A7: 需要去掉可执行程序的头部格式(具体怎么做,忘了),然后在处理程序的时候指定加载内存的addr,然后加载到这个addr,执行。

      Q8: printf 是怎么实现的?它为什么可以又不定数量的参数?为什么它能够在终端上输出字符串?

      A8: printf 是通过调用系统调用write实现的,不定数量的参数依赖于stdarg.h,具体实现未知,因为终端输出也是作为文件描述符处理。

      Q9: Hello World 程序在运行时,它在内存中是什么样子的?

      A9: 应该是映射在物理内存的一块地方,未知.

           通过回答这些问题,自己才意识自己基础多么薄弱.

    二. 计算机系统软件体系结构采用一种层的结构

      “Any proble in computer science can be solved by another layer of indirection."

           这让自己之前写的一个线程池,朋友看后鄙视我好久,认为内聚性太低,当时我承认,可我也同时儿认为我这通用性强。

            我那线程池不能作为一个接口,所以只能算dogshit.

    三. 为什么要分段分页

         解决内存使用的三个问题:

      1. 地址空间不隔离

      2. 内存使用率低

      3. 程序运行地址不确定

         分段通过虚拟地址映射,解决1,3

          分页解决2

    四. 线程基础

         一个标准的线程由线程ID,当前指令指针,寄存器集合和堆栈组成。共享(代码段,数据段,堆,以及一些进程极资源)

         分类: I/O密集型线程,CPU密集型线程。前者一般优先级高

         优先级改变方式:

      1. 用户指定优先级

      2. 根据进入等待状态的频繁程度提升或降低优先级

      3. 长时间得不到调度提升

    五. 线程安全

      1. 线程同步

                 原子操作,锁(二元信号量,互斥量,临界区,读写锁,条件变量)

                 信号量在整个系统中可以贝任意线程获取并释放,互斥量只能被获取的线程释放;临界区的作用范围仅限于本进程,互斥量在系统任何进程中可见,

      除此,具有相同性质;条件变量类似与一个栅栏,线程可以一次唤醒一个或所有等待线程。应用如:线程池

      2. 可重入与线程安全

             @1:线程可重入情况:

          多个线程同时执行这个函数

          函数自身(可能经过多层调用之后)调用自身。

        @2:可重入条件:

          不使用任何(局部)静态或全局的非const变量

          不返回任何(局部)静态货全局的非const变量

          仅依赖调用方提供的参数

          不依赖任何单个资源的锁

          不调入任何不可重入的函数

      3. 过度优化

        @1: 保护区域数据因编译过度优化,存放到寄存器中

        @2:编译器为了提高效率,调整两条互不影响相邻指令的执行顺序

             使用volatile可以组织变量缓存到寄存器而不被写回,也可以组织编译器调整操作volatile变量的指令顺序,但不能阻止CPU动态调度程序.

        C++ new的两个步骤:分配内存,调用构造函数

    六. 线程模型

      1.  一对一模型

      2. 多对一模型

      3 .多对多模型

      linux 内核线程和用户线程?

          

  • 相关阅读:
    函数调用栈的总结
    Calling convention-调用约定
    函数可以返回结构体的原因
    pthread_join/pthread_exit的用法解析
    线程退出的几种方式和资源回收【线程编程中避免内存泄漏】
    线程状态与tcb、线程的生命周期
    pthread_cleanup_push vs Autorelease VS 异常处理
    thread.h
    Thread Control Block
    线程与cpu
  • 原文地址:https://www.cnblogs.com/chagmf/p/3775554.html
Copyright © 2011-2022 走看看