day35

it2022-05-09  33

今日内容:

import timefrom multiprocessing import Process, Queueimport random# 自己理解 :两个进程之间相互进行数据传输就要通过一个中间介质,这个介质即共享文件有四种方法;# 1,管道,单向传输,都是二进制# 2.文件,是从硬盘中创建共享文件,再把数据传输到内存,虽然使用数据类型广,可传输的数据量大,但是传输速度慢,效率低# 3,socket 编程复杂度较高# 4,就是创建一种共享的容器:# 1> Manager类 它可以开启一个共享的dict 或者list,可以提供很多数据结构# 它所闯将出来的数据结构具备进程间共享的特点,但是出现的不明问题太多,不建议使用# 2> Queue 类 队列 即一个容器 是极力推荐的方法,重点掌握,# 特点:自带锁,不容易出现数据错乱的问题 先进先出def eat(q): # 消费 for i in range(10): res = q.get() #从q队列中获取元素 print(res) time.sleep(random.randint(0, 2)) print(res, "吃完了")def mak_dog(q): # 生产者 for i in range(10): time.sleep(random.randint(0, 2)) print("第%s做完" % i) res = "第%s制作完成!" % i q.put(res) #往q中塞数据if __name__ == '__main__': q = Queue() #增加q队列 eat_p = Process(target=eat, args=(q,)) mak_d = Process(target=mak_dog, args=(q,)) eat_p.start() mak_d.start() 守护进程: 作用: 父进程交给子进程一个任务,然而父进程先于子进程结束了,子进程的任务也就没必要继续执行 一个进程可以设为另一个进程的守护进程、 特点是:被守护的进程挂了,守护进程也就挂了 p.daemon = True 呆萌""" 互斥锁:相互排斥的锁 锁的本质就是一个标志 这个标志有两个状态 一个为锁定 一个为未锁定 用途:当多个进程要同时操作同一个资源时,就会造成数据错乱,通常将写入操作加锁,读取操作不需要加锁 加锁会把原本并发的任务,修改为串行,降低了效率吗,保证了数据的安全性 加锁可以指定一部分代码串行,其他任然可以并发 join 也可以将任务变为串行,它固定了任务的执行顺序,就是顺序固定,按顺序执行,不公平 join会是子进程的代码全部串行执行,并且主进程也会阻塞,是执行一个子进程,不能执行一行代码,他执行,别的子进程只能等待 注意:要想保证安全,必须保证大家用的都是同一把锁 不能对同一把锁连续执行acquire 将会导致锁死 from multiprocessing import Process.Lock def task(lock): lock.acquire() print("任务") lock.release() if __name__ == '__main__': lock = Lock() 实例化这个类 p = Process(target=task,args=(lock,)) p.start()生产者消费者模型def eat(q): # 消费 for i in range(10): res = q.get() #从q队列中获取元素 print(res) time.sleep(random.randint(0, 2)) print(res, "吃完了")def mak_dog(q): # 生产者 for i in range(10): time.sleep(random.randint(0, 2)) print("第%s做完" % i) res = "第%s制作完成!" % i q.put(res) #往q中塞数据if __name__ == '__main__': q = Queue() #增加q队列 eat_p = Process(target=eat, args=(q,)) mak_d = Process(target=mak_dog, args=(q,)) eat_p.start() mak_d.start其中需要队列这个容器Queue 解决双方效率,不平衡这个问题 线程 概念:线程是操作系统最小的运算调度单位,被包含在进程中,一个线程就是一个固定的执行流程 线程和进程的关系: 进程是一个资源管理单位,其包含了运行程序所需的所有资源 线程不能单独存在 必须存在于进程中, 线程才是真正的执行单位,没有线程,进程中的资源无法被利用起来,所以一个进程至少包含一个线程,称之为主线程 线程可以由程序后期开启,自己开启线程称之为子线程--*************-+------------ 使用线程的目的只有一个: 就是提高效率 线程如何使用:*****************重点 第一种方法: from threading import Thread def task(): print("子线程run") print("子线程over" #执行顺序不固定 如果开启线程速度足够快 可能子线程先执行 # p = Thread(target=task) # p.start() if __name__ == '__main__': t = Thread(target=task) t.start() print("主线程over") 结果为:子线程run 主线程over 子线程over 第二种方法:from threading import Thread class MyThread(Thread): 继承Thread类 def run(self): print("子线程run") MyThread().start() print("主线程over") 总结:使用方法和多进程方法一模一样,开启线程的代码可以放在任何位置,但是开启进程必须放在判断的下面 线程的特点:1 创建开销小 2 同一个进程中的多个线程线程数据是共享的 3,多个线程之间是平等的没有父子关系,所有线程的pid都是一样的(子进程) 案例: from threading import Thread import time, os def task(): print(os.getpid()) if __name__ == '__main__': st_time = time.time() ts = [] for i in range(1000): t = Thread(target=task) t.start() ts.append(t) print("主线程over") print(st_time) 了解: from multiprocessing import Process #from threading import Thread import time,os def task(): print(os.getpid()) if __name__ == '__main__': st_time = time.time() ts =[] for i in range(100): t = Process(target=task) t.start() ts.append(t) print("主进程over") print(st_time) 守护线程: 一个线程可以设置为另一个线程的守护线程 主线程代码执行完毕后 不会立即结束 会等待其他子进程结束 主 会等待非守护线程结束后结束 守护线程会等到所有的非守护线程结束后结束 前提是除了主线程之外,还有别的非守护 当然如果守护线程已经完成任务。立马就结束 即如果皇帝活着,守护者 妃子死了,皇帝正常运行,皇帝死了,无论守护者是否完成任务,都立即结束

转载于:https://www.cnblogs.com/Fzhiyuan/p/10976752.html


最新回复(0)