秋招C++开发学习之路day10

day12(fork、引入线程后变化(资源、调度等)、进程线程通信方式、调度算法、死锁产生条件)

  1. forward_list 单向链表,deque双端队列,
  2. fork()产生一个新的进程。线程不能跨机器迁移。 同一进程下的线程共享地址空间。
    data section存放全局变量,可以被同一进程下的线程共享。
  3. (1)调度上。传统操作系统上,拥有资源和独立调度的基本单位都是进程。
    引入线程后,线程是独立调度的基本单位,进程是拥有资源的基本单位吗。
    (2)资源上。进程都是拥有资源的基本单位,线程不拥有资源(有一点必不可少的资源),但是线程可以共享棣属于进程的系统资源。
    (3)并发性。引入进程以后,不仅进程可以并发,同一进程的线程也可以并发。
    (4)系统开销。创建和撤销进程时,系统都要为之分配或回收资源,如内存空间、I/O设备等。所以操作系统的开销远大于创建或撤销线程的开销。
    (5)地址空间,(6)通信,进程通信需要操作系统,而线程通信可以直接读写进程数据段来进行通信。
  4. Linux 线程间的通信:互斥体(互斥量)、信号量、条件变量。
    Windows进程间通信:管道、共享内存、消息队列、信号量、socket。
    Windows线程间通信:临界区、互斥量、信号量(信号灯)、事件。
    临界区只能用来同步本进程的线程,而互斥量、信号量、事件可以跨进程使用来进行同步数据操作。
    临界区是非内核对象,互斥体是内核对象。临界区和互斥体都可在Windows平台,Linux只能用互斥体。
  5. 典型调度算法中,短作业优先算法(SJF)平均等待时间、平均周转时间最少。
  6. 产生死锁的四个必要条件,互斥条件、不剥夺条件、请求和保持条件、循环等待条件。

day13(extern、auto_ptr等智能指针、fork、静态函数、重载、strcpy、strlen、malloc、rxrc、内存对齐)

  1. extern放在变量或者函数前表示,该函数或者变量已经在其他地方定义。
  2. C++中的四个智能指针。
    智能指针的作用是管理一个指针,因为存在以下这种情况:申请的空间在函数结束时忘记释 放,造成内存泄漏。使用智能指针可以很大程度上的避免这个问题,因为智能指针就是一个类,当超出了类的作用域是,类会自动调用析构函数,析构函数会自动释放资源。所以智能指针的作用原理就是在函数结束时自动释放内存空间,不需要手动释放内存空间。

auto_ptr<类型>对象(赋值)。p2=p1,p1有赋值,这时不会保存,但是再访问p1时会出错,因为存在潜在的内存崩溃问题。
unique_ptr<类型>对象(赋值),pu1=pu2,pu2已经有初值,就会报错。仅为右值赋值时会出错,只能pu1=unique_ptr<>pu2(赋值)。也可以用 pu1=move(pu2),进行赋值。
share_ptr实现共享式拥有概念,多个智能指针可以指向同一个对象。在最后一个引用被销毁时释放相关资源。use_count()返回计数的个数,就是资源所有者的个数。个数为0,释放资源。
wead_ptr是一种不控制对象生命周期的智能指针,主要用来防止share_ptr两个指针相互引用,计数就会一直不为0,出现死锁。
解决内存泄漏,引入了weak_ptr弱指针,他的构造函数不会修改引用计数的值,从而不会对对象的内存进行管理,不指向引用计数的共享内存,但可以检测到所管理的对象是否已经被释放,避免了非法访问。

智能指针主要用于管理在堆上分配的内存,它将普通的指针封装为一个栈对象。当栈对象的生存周期结束后,会在析构函数中释放掉申请的内存,从而防止内存泄漏。C++ 11中最常用的智能指针类型为shared_ptr,它采用引用计数的方法,记录当前内存资源被多少个智能指针引用。该引用计数的内存在堆上分配。当新增一个时引用计数加1,当过期时引用计数减一。只有引用计数为0时,智能指针才会自动释放引用的内存资源。对shared_ptr进行初始化时不能将一个普通指针直接赋值给智能指针,因为一个是指针,一个是类。可以通过make_shared函数或者通过构造函数传入普通指针。并可以通过get函数获得普通指针。

  1. fork()会创建一个新的进程,几乎与调用fork()的进程一模一样,两个进程都会继续进行。
  2. 静态函数在编译的时候就已经确定运行时机,虚函数在运行的时候动态绑定。虚函数因为使用了虚函数表机制,调用的时候会增加一些内存开销。
  3. 重载,重写:子类继承父类,父类中的函数是虚函数,子类中重新定义了这个虚函数,这种情况就是重写。
  4. strcpy是字符串拷贝函数,因为没有指定长度,可能会拷贝越界,安全版本是strncpy函数。
    strlen函数是计算字符串从开始到’\0’之间字符的个数。
  5. malloc/free是C语言的库函数,对于类类型的对象不会调用构造函数和析构函数。
  6. exec函数可以加载一个elf文件去替代父进程,从此父进程和子进程就可以运行不同的程序了。exec执行成功则子进程从新的程序开始运行,无返回值,执行失败返回-1。
    fork从父进程返回子进程的pid,从子进程返回0。
    调用wait的父进程将会发生阻塞,直到有子进程状态发生改变,执行成功返回0,失败返回-1。
  7. 内存对齐
    在C++中规定了空结构体和空类的内存所占大小为1字节,因为规定任何不同的对象不能有相同的地址。
    C语言中空的结构体在内存中所占大小为0。

为什么要内存对齐?

  1. 平台原因(移植问题):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则会抛出异常。
  2. 性能原因:数据结构(尤其是栈)应该尽可能的在自然边界上对齐。原因在与,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次。
上一篇:网络爬虫day10


下一篇:DAY10