Linux下进程和线程的概念和控制

进程描述:

浅层:运行中的程序,程序运行的动态描述

程序的二进制指令加载到内存中,需要有一个pcb来描述它,这个pcb在Linux下是一个struct task_struct结构体

进程就是pcb,是操作系统对一个运行中程序的描述。通过这个描述实现对程序运行的调度

操作系统要运行某个程序时,找到其对应的pcb,将其中保存的各种描述信息(上下文数据)加载到cpu寄存器中,完成程序的轮询调度

其中的内容有:内存指针,程序计数器(上一次程序运行到的位置),上下文数据(上一次CPU寄存器上处理的数据),进程标识符PID,IO信息,进程状态,记账信息

进程创建:

pid_t fork(void);复制父进程创建子进程,创建子进程就是创建一个大部分信息与父进程相同的pcb

父子进程数据独有,代码共享。调度的程序相同。数据互相独立

流程:写时拷贝技术:

子进程创建成功后,数据和代码依然和父进程在物理内存中共用一份,当该块内存中数据改变时,为子进程单独开辟一块空间拷贝数据,只由子进程使用

终止:退出进程 main()中return;调用的当中想退出,使用库函数的exit接口(退出时把数据写入了缓冲区);调用系统调用_exit接口(退出时直接释放资源,退出进程,不会刷新缓冲区)

替换:改变pcb调度运行的程序(改变pcb中内存指针),有exec函数族

进程状态

程序的运行调度通过操作系统完成,不是每个程序每时每刻使用cpu处理数据。

比如I/O操作,磁盘进行I/O,不需要cpu,此时需要将程序置为阻塞状态

就绪:拿到时间片就能运行

运行:正在CPU上运行

阻塞:暂时不运行

Linux下进程的状态:

运行态 R:就绪/运行

可中段休眠态 S:当前的阻塞能够被中断

不可中段休眠态 D:磁盘休眠,当前的阻塞不能够被中断,等待条件满足自己醒来

停止态 T:停止运行,什么都不干

死亡状态、追踪状态

僵死态 Z:进程已经退出但是资源没有完全被释放的一种状态

僵尸进程:僵死状态的进程pcb还在,剩下的资源几乎完全被释放,进程退出了会保存退出返回值,直到被父进程获取或处理

产生:子进程先于父进程退出,向父进程发送SIGCHLD信号,但是SIGCHLD信号默认处理方式是忽略处理,因此父进程无法直接获知子进程状态

危害:资源泄漏

避免:进程等待:父进程一直关注子进程退出状态(进程等待),子进程退出了获得返回值,释放子进程资源。是阻塞操作的原因。接口:wait/waitpid

虚拟地址空间

本质:mm_struct结构体

是对内存的描述,是一块虚假的空间。

每个进程都有自己连续的虚拟地址空间,进程通过虚拟地址间接访问物理内存(通过页表完成)

优点:

虚拟地址随意使用,物理地址按需分配,不需要连续。实现了整块数据在物理内存中的离散存储,提高了内存利用率

虚拟地址访问可以进行内存访问控制,通过对地址的描述确定其操作权限,提高了内存访问控制

每个进程虚拟地址空间独有,互不交叉,提高进程独立性

页表如何实现虚拟到物理的转换?

映射关系与内存管理方式息息相关

分段式:内存分为多段(代码段、数据段),好处:对编译器友好,内存管理方便,缺点:无法解决内存利用率低

分页式:将整个内存分为非常多个内存页面,通过映射关系,将使用连续内存页数据放到不同物理内存上实现离散式存储,优点:内存利用率高

段页式:以上两种集合,将整个内存先分段,再每个分段进行分页(通常)

分页式实现:

虚拟地址分为页号:内存编号,页内偏移:变量空间在内存起始页的偏移量

232的4g内存,每个分页4096字节,那么总共有220页,内存编号占了220位,偏移量占了212

每个虚拟空间有自己的页表,是一个结构体,巨现为表格

pcb申请mm_struct,通过页表映射物理内存,子进程将这一切都会复制,指向同一块物理内存,发生改变后再重新开辟

分页式管理

缺页中断:缺页中断标志位表示为0,代表地址要访问的数据没在物理内存上

产生原因:

内存置换算法,LRU:

线程概念

是进程中的一条执行流,是CPU调度的基本单元。在Linux下通过pcb实现线程,一个进程中可以有多个线程,这些pcb共享同一个进程中的大部分资源,linux下线程也称为轻量级进程

进程是系统进行资源分配的基本单元,线程是cpu调度执行的基本单元。系统为进程分配一整块资源,由线程共用大部分资源,具体程序运行调度管理通过线程pcb实现

线程间独有与共享

独有:标识符,栈(有独立的栈线程才能独立的运行),上下文数据(寄存器,cpu资源存放的单元。cpu切换调度时每一个执行流都要保存自己的上下文数据),信号屏蔽字(用于单独阻塞),errno(系统调用错误信息)

共享:虚拟地址空间,文件描述符信息,信号处理方式(信号发送的单位是进程,针对一整个进程发挥效果),工作路径

多任务的多执行流并发/并行处理

并发:多任务的轮询处理 只有一个cpu,多个线程

并行:多个cpu或核,一个核有一套独立寄存器,同时处理

实现并发/并行处理的两种处理方案

多线程:

1.线程间通信更加灵活(包括进程间通信方式,因为共享虚拟地址空间还有全局变量以及函数传参)

2.线程创建和销毁占用的时间和资源成本降低(因为资源共享)

3.同一个进程中线程间的调度切换成本更低

多进程:

1.健壮性更强(比如一个进程崩了其他不受影响。例子:shell,不断捕捉输入执行shell指令,执行即创建一个子进程,出问题也是子进程崩溃,shell不受影响;服务器中新连接让子进程处理,出现异常只有客户端异常,不会出现整个服务器崩溃)

2.有些系统调用接口针对整个进程产生效果(exit退出整个进程)

共同的优点:多任务的多执行流并发/并行处理,充分利用cpu资源,压缩IO阻塞时间,提高任务处理效率

多执行流进行多任务处理时,线程数不是越多越好,多了反而增加调度切换成本。根据实际情况进行压力测试,

线程控制
创建:
int pthread_create(pthread_t *tid, pthread_attr *attr, void*(thread_rontine)(void*), void* arg)线程id,线程属性,线程入口函数,通过入口函数指针传入参数传递给线程的数据
终止:

1.线程入口函数处return(线程入口函数运行完毕,线程会退出)

void pthread_exit(void *retval);

控制线程可以在任意位置退出

int pthread_cancel(pthread_t tid);

取消一个线程(线程可能没有运行结束)

等待:

等待一个线程退出,获取线程返回值,释放线程资源

线程有一个分离属性,默认为joinable状态,处于该状态的线程退出之后需要被等待才能释放资源

int pthread_join(pthread_t tid, void **retval)被等待的线程标识符,获取线程退出返回值
分离:

线程的分离属性设置为detach状态,该状态下线程退出之后自动释放资源,该状态下线程不能被等待

int pthread_detach(pthread_t tid);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值