目录
一. 僵尸进程/孤儿进程/守护进程
二 线程的同步和异步
三. 线程间通信
3.1 共享内存
3.2 互斥锁
3.3 条件变量
3.4 信号量
3.5 读写锁
3.6 事件
3.7 线程局部存储
四. 进程间通信
3.1 管道
3.2 消息队列
3.3. 共享内存
3.4 信号量
3.5 套接字
3.6 内存映射文件
3.7 信号
五. 字节对齐
六. 内存分配的方式
七. 智能指针
八. 常见的内存错误及对策
一. 僵尸进程/孤儿进程/守护进程
僵尸进程:进程已经完成执行,但其父进程还未读取其退出状态,因此在进程表种仍存在。它的存在是为了让父进程获取子进程的终止状态,之后才会完全清除
孤儿进程:父进程已经结束,但它还在运行,操作系统会将孤儿进程的父进程重新指定为'init'进程,以确保它能够被适当管理
守护进程:是系统后台运行的进程,它在系统启动时由init进程或类似的系统进程启动,并在系统运行期间保持活跃,直到系统关闭;它们被称为守护进程是因为它们像守护者一样在后台持续工作,确保系统的正常运作和服务的持续提供
二 线程的同步和异步
同步:当一个线程需要等待另一个线程完成某个任务时,他会阻塞直到任务完成,例如,使用锁来保证一个线程在访问共享资源时,其他线程不能同时访问,从而避免数据冲突。我们可以用互斥锁,信号量等来实现同步
异步:线程的操作不会阻塞主线程,任务可以在后台运行,主线程继续执行其他操作。例如,异步I/O操作允许线程发起文件读写请求后立即继续执行其他代码,直到I.O操作完成。
三. 线程间通信
3.1 共享内存
允许多个线程共同访问一块内存区域,数据不需要复制或传递,而是直接在共享内存区域中进行读写
3.2 互斥锁
确保在任何时刻只有一个线程可以访问共享资源。防止多个线程同时访问或修改共享数据。
3.3 条件变量
允许线程在某些条件满足时进行等待和通知。
3.4 信号量
内部维护一个计数器,表示可用资源的数量,这个计数器可以增加或减少,依赖于线程对信号量的操作
3.5 读写锁
是一种同步机制,用于在多线程环境中对控制对共享资源的访问。与互斥锁不同,读写锁允许多个线程进行读写操作,但在有线程进行写操作时,会组织其他线程进行读或写操作。
3.6 事件
指的是一种发生在系统中的动作,状态变化或信息
3.7 线程局部存储
使得每个线程都拥有其专属的存储区域,从而避免不同线程之间的共享数据冲突
四. 进程间通信
3.1 管道
管道又可以分为:
单向管道:数据从一个进程的写段流向另一个进程的读端
双向管道:由两个单向管道组成,实现双向通信,一个管道用于从进程A到进程B,另一个管道用于从进程B到进程A
命名管道(FIFO):命名管道允许不相关的进程通过一个具名文件进行通信,这种管道存在于文件系统中,使用类似文件的接口进行读写操作
3.2 消息队列
允许进程将数据发送到一个队列中,另一个进程可以从这个队列中接收信息。
3.3. 共享内存
允许多个进程访问同一块物理内存区域。
3.4 信号量
3.5 套接字
提供了与网络套接字相似的功能,但只在本地计算机上有效。它们使用文件系统中的文件作为通信的端点,而不是网络地址和端口。
3.6 内存映射文件
一种将文件内容直接映射到进程的虚拟内存空间的机制,允许进程像操作内存一样访问文件。
3.7 信号
信号是一种用于通知进程发生特定事件的机制,信号可以由操作系统或其他进程发送,用于中断当前进程的执行,
五. 字节对齐
字节对齐是一种内存管理策略,用于确保数据在内存中按照一定的规则对齐
六. 内存分配的方式
静态内存分配:静态内存分配在程序编译时完成,即在程序执行之前就已确定了内存的分配,分配的内存大小和位置在编译阶段就固定下来
动态内存分配:在程序运行时请求内存,这样可以根据实际需要动态调整内存的大小和位置。常用方法:堆内存分配,比如malloc,free,在c++中是new,delete
内存池:内存池是一种分配内存块并在这些块中进行管理的方法,内存池用于减少频繁的内存分配和释放操作的开销
内存映射:内存映射将文件或其他对象的内容直接映射到进程的虚拟地址空间。这种方式可以将文件内容视作内存进行访问,支持大文件和进程间的共享内存。
七. 智能指针
是C++中用于管理动态分配内存的一个工具,提供了自动化的内存管理方式。智能指针不仅可以帮助避免内存泄漏,还可以简化内存管理。智能指针通常封装了普通指针,并提供了自动化释放内存的机制。
而之所以智能指针能够实现自动内存管理,是因为它们封装了指针并实现了内存管理的策略,主要依赖于:RAII,是一种编程技术,其中资源的生命周期与对象的生命周期绑定。引用计数:是一种内存管理方法,通过维护一个计数器来跟踪有多少个智能指针实例共享同一块内存或资源;
std::unique_ptr:
std::unique_ptr
是一种独占拥有的智能指针,确保一个对象在同一时间只有一个 unique_ptr
实例指向它。
std::shared_ptr
std::shared_ptr
是一种共享拥有的智能指针,允许多个 shared_ptr
实例共同拥有同一个对象。
std::weak_ptr
std::weak_ptr
是一种不改变引用计数的智能指针,用于观察 shared_ptr
管理的对象,但不会阻止对象被销毁
八. 常见的内存错误及对策
常见的内存错误有内存泄漏,悬挂指针,双重释放,缓冲区溢出等。
内存泄漏:是指程序分配了内存但未能释放,导致无法再访问这块内存。
悬挂指针:已经被释放内存的指针,访问这样的指针会导致未定义行为
双重释放:对同一块内存进行多次释放
缓冲区溢出:写入超出数组或内存块的边界