Linux——进程和线程
1、什么进程什么是线程进程一个正在运行的程序线程进程内部的一条执行路径序列进程是操作系统资源分配基本单位拥有独立地址空间与系统资源进程间相互隔离通信开销大线程是进程内执行分支为 CPU 调度基本单位同进程线程共享资源仅保有少量私有栈与寄存器创建切换成本低也伴随线程同步安全问题。线程依附进程存在进程可拆分多线程并发工作。2、为什么需要多线程希望有多个处理器处理器有多个核心处理起来的速度更快3、为什么需要进程间通信因为进程的独立性每个进程操作系统都会为该进程创建task_struct(pcb),其中就包含虚拟地址空间描述页表信息。因此每个进程内部数据存储所分配的地址都是虚地址这也是为什么进程间通信需要操作系统提供进程间通信资源的原因让操作系统给多个不同的进程分一块大家都能访问的空间4、内存置换当内存不够用了操作系统如何处理内存置换操作系统认为内存中的很多数据并不是一直在访问热数据因此当内存不够用的时候操作系统就会根据一定的算法将指定内存中的数据置换出去存的硬盘存放这些数据的硬盘区有个专有名词交换分区LRU:最久未使用 LFU:最少未使用FIFO先进先出5、缺页中断当访问内存数据的时候通过页表将虚拟地址转换为物理地址但是转换的时候发现页表中置为了缺页中断位当前这个虚拟地址对应的那块内存数据没有在物理内存中缺页中断的处理从交换分区将数据重新置换到内存中更新页表信息分段式内存管理将代码分成一个一个的代码段....对程序内的内存管理比较友好但是数据会堆在一定区域造成内存浪费段页式内存管理对内存分段在每个段内进行分页6、进程控制创建退出等待程序替换1.进程创建pid_t fork();功能通过复制父进程的方式创建一个子进程复制了什么缓冲区调度切换相关的上下文信息虚拟地址空间页表信息文件描述符信息创建子进程这里使用了写时拷贝技术创建子进程之后子进程与父进程指向同一块内存区但是当任意一方要对一块内存区域的数据进程修改则给当前进程重新开辟一块空间拷贝新数据进去大大提高了创建子进程的效率pid_t pidfork(); if(pid0) { //子进程运行 } else { //父进程运行 }1复制了虚拟地址空间复制出来的子进程要执行的代码要处理的数据跟父进程是一样的2复制了程序调度上下文信息为什么fork出来的子进程是从fork之后开始运行pc寄存器保存的是即将要执行的指令地址程序运行到了哪里切换的其他信息正在执行的指令正在处理的数据...2.进程的退出退出终止程序的运行正常退出1在main中return;2在任意位置调用exit()函数——是一个库函数封装了系统调用接口3在任意位置调用_exit()函数——系统调用库函数是对系统调用函数在特定场景下的一些功能补充库函数内部调用了系统调用函数库函数在exit退出的时候会进行用户态空间做一些资源清理eg.刷新缓冲区异常退出程序在运行遇到了某些异常导致程序崩溃异常退出情况下进程的返回值是没有参考意义的3.进程等待父进程创建子进程之后等待子进程退出为什么要等待捕获子进程的退出状态获取他的返回值释放子进程的所有资源避免产生僵尸进程pid_t wait(int* wstatus);pid_t waitpid(pid_t pid,int*wstatus,int options);wstatus:内存包含两个信息1.进程退出原因2.进程退出码处理逻辑先取第七位判断是否为0为0则表示正常退出再取低16位中的高8位当作退出码进行处理4.进程程序替换默认创建子进程之后子进程与父进程的代码段一样的可以通过fork返回值进行分支控制这样会导致两个不同的功能放在一个程序中实现代码较为臃肿如何让子进程重新运行另一个程序呢使用程序替换1.将新程序指令数据加载到内存中2.将子进程的页表映射信息初始化并且更新映射到新的内存区域加载到内存的新程序3.初始化调度上下文信息让当前进程pc寄存器指向新程序指令的起始位置exec函数族execlexeclpexecleexecvexecvpexecve1l和v的差别设置程序运行参数的差别I是通过不定参逐个给与v是组织成为数据一次给与2有没有p的差别是否会到系统path环境变量指定的路径下去找这个程序execl(/bin/ls) execlp(ls)3)有没有e的差别子进程中是否自定义环境变量7、进程中打开的文件信息管理进程的i/O文件的输入输出系统调用open,read,write,lseek,close文件描述符的本质是一个数组下标1一个进程内部能够打开的文件数量是有上限的2重定向就是修改描述符所对应的描述信息而实现的重定向修改数据的输出位置每个进程运行起来之后会默认打开三个文件标准输入-键盘标准输出-显示器错误输出-显示器描述符:08、进程间通信进程间通信就是让操作系统为进程之间提供一个公共内存访问区。原因进程之间具有独立性根据不同的应用场景操作系统提供了多种不同的方式管道数据传输共享内存数据共享消息队列数据传输信号量同步控制追问信号网络通信1.管道管道的本质内核中的一块缓冲区公共特性1半双工通信可以选择方向的单向通信2管道的数据写满了继续write就会阻塞管道中没有数据read会阻塞3管道读端关闭则write就会触发异常-SIGPIPE所有写端关闭read取完所有数据后继续read不在阻塞而且返回04数据传输是字节流传输以字节为单位进行传递并且有序交付先进先出5生命周期随进程所有打开管道的进程退出内核中的管道这个缓冲区就会被释放匿名管道没有名字的管道没有标识符其他的进程怎么找到这个管道跟我通信呢特性只能用于具有亲缘进程关系的进程间通信创建子进程复制父进程的文件信息表操作在创建子进程之前创建管道然后创建子进程子进程就是复制进程内部打开的文件信息int pipe(int fd[2])接收两个描述符fd[0]用于读fd[1] 用于写命名管道有名字的管道可以被所以进程找到可以用于任意进程间通信名字一个管道文件这个只是一个标识名字本质上管道就是内核的缓冲区接口mkfifo(filename,flag);2.共享内存本质内核中创建的一块内存空间共享原理将这块内存空间映射到不同的进程的虚拟地址空间操作shmget(key_t key,size,flag)以及一个标识key创建共享内存void* shmat(int id);将创建的共享内存映射到自己的地址空间中返回映射后的地址通过shmat返回的地址对共享内存的数据进行操作void shmdt(int id);解除映射int shmctl(int id,oprator -IPC_RMID) 删除共享内存我删除共享内存的时候其他的进程正在使用呢一旦进行了删除内核中移除了共享内存的名字禁止其他进程继续映射但是不会直接删除这块共享内存而是共享内存的描述信息中有个计数器当前映射连接数因此当当前映射连接数为0时才会自动释放ipcs查看共享内存