进程与线程 - 日理万妓 2023-10-09 10:21 5阅读 0赞 # 操作系统/进程 # ## 程序 ## #### 1. 程序是什么? #### 一堆文件 #### 2. 进程是什么? #### 进程就是一个正在执行的文件/程序 #### 3. 进程被谁执行? #### CPU最终运行你的程序 操作系统调度作用,将你的磁盘上的程序加载到内存 , 然后交由CPU去处理 , 一个CPU正在运行的一个程序 , 就叫开启了进程 ## 操作系统 ## #### 1. 操作系统的定义 #### 操作系统是存在于硬件和软件之间, 管理 , 协调 , 控制软件和硬件 #### 2. 操作系统的作用 #### 1. 把复杂的硬件操作 , 封装成简单清晰的接口 1. 合理调度分配多个进程与CPU的关系 ## 进程介绍 ## 1. 串行: 所有的进程 , CPU一个一个的解决 2. 并发: 单个CPU , 同时执行多个进程(来回切换的运行) 3. 并行: 多个CPU , 真正的同时运行多个进程 4. 阻塞: 例如 I/O #### 进程的创建 #### 开启进程 : 内存中开空间 , 加载资源与数据应 , 调用CPU执行 , 可能还会使用这个空间的资源 由主进程创建一个或多个子进程 , 第一个主进程是操作系统 py文件中 开启新的子进程 , 只是一个新的入口 , 将全局的所有数据复制一份给子进程 #### 进程的id #### 1. 终端: tasklist | findstr appname 2. pycharm中 os.getpid() os.getppid() #### join 阻塞 #### join阻塞的是主进程 自适应sleep #### 守护进程 #### daemon 守护进程 主程序死亡子程序跟着死亡 ## 守护进程 from multiprocessing import Process x = 1000 def task(): global x print(x) x = 2 print(id(x)) test() ##@2 def test(): print('我被执行了') if __name__ == '__main__': p = Process(target=task) ##@2 p.daemon() = True #先声明 p.start() # 再开启 print(id(x)) from multiprocessing import Process import time ## 并发 join def task(name,s): time.sleep(s) print(name) def test(): print(11111) if __name__ == '__main__': t1 = time.time() ## 并发 obj_l = [] for i in range(1,4): p = Process(target=task,args=('x'*i,i)) p.start() obj_l.append(p) for func in obj_l: func.join() print(time.time()-t1) print('主进程') ## 子进程开启时 , 会复制主进程的内容 看@2 from multiprocessing import Process x = 1000 def task(): global x print(x) x = 2 print(id(x)) test() ##@2 def test(): print('我被执行了') if __name__ == '__main__': p = Process(target=task) ##@2 p.start() p.terminate() ## 终止进程 p.is_alive() ## 查看进程是否活着 print(id(x)) #### 僵尸进程 #### 僵尸进程是当子进程比父进程先结束 , 而父进程没有回收子进程 , 释放子进程占用的资源 , 此时子进程将成为一个僵尸进程 #### 孤儿进程 #### 如果父进程先退出 , 子进程被init接管 , 这时子进程为孤儿进程 #### 进程通信 #### 1. 进程在内存级别不允许通信 2. 可以同时操作一个文件 , 多进程抢占同一资源时 , 保证结果正确 , 公平性竞争 , 必须保证串行 , 并且上锁 3. 进程通信要用队列 , FIFO #### 互斥锁 #### from multiprocessing import Process from multiprocessing import Lock import time ## 互斥锁 一锁一解 遇见阻塞 , cpu还是会切换进程, 但是遇到锁了 , 发现锁被占用 def task(lock): lock.acquire() time.sleep(2) print(11) lock.release() def task2(lock): lock.acquire() time.sleep(1) print(222) lock.release() if __name__ == '__main__': lock = Lock() p1= Process(target=task,args=(lock,)) p2 = Process(target=task2,args=(lock,)) p1.start() p2.start() #### 队列 Queue #### q = Queue(maxsize = 3) q.put(1) q.put('str') q.put(obj) q.put(xxx,block = True) # block 默认为True 队列长度是3 再放入一个就会阻塞 q.get() q.get() q.get(timeout = 3) # 取数据 , 也有block 用法相同 , timeout表示最长阻塞时间 #### 生产者消费者模型 #### 合理的调控 , 多个进程生产数据与提取数据 , 中间数据使用队列Queue 对生产者消费者解耦 , 平衡了生产力和消费力 , 多用于解决并发的问题 ## 线程 ## 进程主要任务 : 开启空间 , 加载数据 , 静态的 线程: 执行代码 , 动态的 #### 线程和进程的对比 #### 1. 开启进程 : 开销非常大 ; 开启线程开销非常小 2. 开启多进程速度慢 , 开启多线程速度快 3. 进程之间理论数据不能共享 , 同一进程下的线程是可以数据共享的 # threading 方法 from threading import Thread import threading def task(): print(11) def task2(): print(22) if __name__ == '__main__': t1 = Thread(target=task) t2 = Thread(target=task2) t1.start() t2.start() print (threading.current_Thread) # 当前线程 print (active_count()) # 当前存活线程 print(threading.enumerate()) # 枚举线程 #### 守护线程 #### 与守护进程不同 , 守护线程要等到所有线程(非守护线程)结束后才结束 #### 递归锁 一把锁 RLock #### 相同线程可以重复上锁 , 解锁也要解相应的次数 ## 解决死锁的问题 from threading import Thread from threading import RLock import time rlock = RLock() class MyThread(Thread): def run(self): self.f1() self.f2() def f1(self): rlock.acquire() print(f'{self.name}获取的了rlock') rlock.acquire() print(f'{self.name}获取的了rlock') rlock.release() print(f'{self.name}释放了rlock') rlock.release() print(f'{self.name}释放了rlock') def f2(self): rlock.acquire() print(f'{self.name}获取的了rlock') time.sleep(1) rlock.acquire() print(f'{self.name}获取的了rlock') rlock.release() print(f'{self.name}释放了rlock') rlock.release() print(f'{self.name}释放了rlock') if __name__ == '__main__': for i in range(3): t = MyThread() t.start() #### 信号量 #### 一个锁 , 多个坑 , 可允许多个线程同时进入 from threading import Semaphore from threading import Thread import time import random slock = Semaphore(5) def task(i): slock.acquire() print(f'{i},进入') time.sleep(random.randint(1,3)) slock.release() if __name__ == '__main__': for i in range(20): t = Thread(target=task,args=(i,)) t.start() 转载于:https://www.cnblogs.com/albert0823/p/11239024.html
相关 进程与线程 有那么一些零碎的小知识点,偶尔很迷惑,偶尔被忽略,偶然却发现它们很重要,也是各大笔试和面试高频出现考点。这段时间正好在温习这些,就整理在这里,一起学习一起提高!后面还会继续补充 痛定思痛。/ 2022年05月30日 00:19/ 0 赞/ 281 阅读
相关 线程与进程 1.定义 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位. 线程是进程的一个实体,是CPU调度和分派的基本 - 日理万妓/ 2022年05月23日 01:56/ 0 赞/ 131 阅读
相关 进程与线程 [进程与线程][Link 1] 推荐一篇讲解的非常透彻且非常形象的文章,阮一峰的一篇博文。 原文链接:[进程与线程的一个简单解释][Link 2] posted @ 秒速五厘米/ 2022年03月22日 11:09/ 0 赞/ 281 阅读
相关 线程与进程 进程 1. 进程是资源分配的最小单位。 2. 开销: 有独立的代码和数据空间,程序切换开销大。 3. 坏境: 能同时运行多个进程(程序)。 4. 内存: 系统在运 骑猪看日落/ 2022年03月17日 10:14/ 0 赞/ 245 阅读
相关 进程与线程 进程,是一个活动的实体,我们平时所说的程序或者可执行文件并不是一个进程,他们都属于被动实体,只有将程序或者可执行文件调入到内存中才能成为一个活动实体,才能称之为进程。 进程是 小鱼儿/ 2022年01月16日 04:27/ 0 赞/ 290 阅读
相关 进程与线程 进程的定义 由于程序在并发执行时,各次执行的结果不同,所以用“程序”这个概念已无法描述程序的并发执行,所以必须引入新的概念 – 进程来描述程序的并发执行。 根据1978 比眉伴天荒/ 2022年01月15日 01:05/ 0 赞/ 302 阅读
相关 进程与线程 进程至少包含三个组成要素:程序快、代码块以及进程控制块; 进程是系统中资源分配和保护的基本单位; 线程作为CPU的调度和分派的基本单位; 每个进程在创建的时候,至少 Dear 丶/ 2022年01月11日 07:49/ 0 赞/ 325 阅读
相关 进程与线程 一般可以把独立运行的程序看作一个进程,进程之间是相互独立存在的,像qq音乐,谷歌浏览器一样他们都是独立存在的,而且互不影响。 进程想要执行任务必须依赖于线程,进程中的最小执行 ﹏ヽ暗。殇╰゛Y/ 2021年12月03日 10:49/ 0 赞/ 255 阅读
相关 进程与线程 进程与线程: 基本概念: 进程:进程是正在运行的程序的实例。每个进程都有自己的地址空间,一般情况下,它包括文本区域、数据区域和堆栈。文本区域存储处理器执行的代码;数据区 落日映苍穹つ/ 2021年09月26日 13:08/ 0 赞/ 399 阅读
相关 进程与线程 进程与线程 1 进程 1.1 进程的概念 进程就是正在运行的程序,它代表了程序所占用的内存区域 1.2 进程的特点 独立性 进程是系 忘是亡心i/ 2021年09月07日 06:19/ 0 赞/ 608 阅读
还没有评论,来说两句吧...