前提是我是参考GithubPython100天一文写的,结合自己的小练习,总结一下最近面试大厂,发现很多大厂都会问Python的多线程和多线程过程,所以我觉得有必要总结和学习。什么是进程在操作系统中执行的程序,类似于微信和QQ,每个程序都是一个进程的概念,是CPU的最小资源分配单位。操作系统会给进程分配内存空间,每个进程都会有自己的地址空间。用于跟踪进程执行的数据栈和其他辅助数据操作系统管理所有进程的执行并为它们合理分配资源。fork和spawn进程可以通过fork和spawn创建新的进程来执行其他任务。但是新进程有自己独立的内存空间和数据栈,所以不同进程需要使用通信机制(IPC)实现数据共享普通通信机制pipesignalsocket共享内存区CPU最小调度的执行单元特性同一进程下的线程共享相同的上下文与进程相比,线程之间的信息共享和通信更容易。单核CPU系统考虑真正的并发是不可能的,因为在某一时刻,CPU只能运行一个线程,多个线程共享CPU的执行时间。多线程的好处是提高了程序的性能,改善了用户体验。当今使用的几乎所有软件都使用多线程。多线程的缺点就摆在了其他进程的前面。从一个角度来说,多线程程序对其他程序并不友好,因为它占用了更多的CPU执行时间,导致——其他程序无法获得足够的CPU执行时间编写和调试多线程程序需要更高的Python水平对于开发者来说,并发编程的实现方式是多进程,多线程,多进程+多线程,Python中的多进程。Linux下的fork函数。Linux操作系统提供fork()系统调用来创建进程。调用fork()函数是由父进程创建的。子进程子进程是父进程的副本,但是子进程有自己的PIDfork()函数很特别,会返回两次,在父进程中调用fork()会返回子进程的PID子进程,在子进程中调用fork()会得到都是0Python提供的fork函数。os模块提供了fork()。Window下没有fork()调用实现跨平台多进程改造。您可以使用multiprocessing模块的Process类来创建子流程并提供更高级的封装,比如用于批量启动进程的进程池pool,进程间共享的队列Queue使用多进程和不使用多进程的区别pipe(写代码)不使用多进程fromrandomimportrandintfromtimeimporttime,sleepdefdownload_task(filename):print('开始下载%s...'%filename)time_to_download=randint(5,10)sleep(time_to_download)print('%s下载完成!用了%d秒'%(filename,time_to_download))defmain():start=time()download_task('Python从入院到住院.pdf')download_task('北京火锅.avi')end=time()print('总共用了%.2f秒。'%(end-start))if__name__=='__main__':main()执行结果开始下载Pythonfromentrytohospitalization.pdf...Pythonfromentrytohospitalization.pdf下载完成!开始下载PekingHot.avi用了10秒...PekingHot.avi下载完成!耗时9秒,共计19.02秒。可以看到需要等第一个文件下载完成后才能下载第二个文件。效率很低。使用多进程fromrandomimportrandintfromtimeimporttime,sleepfrommultiprocessingimportProcessdefdownload_task(filename):print('Startdownloading%s...'%filename)time_to_download=randint(5,10)sleep(time_to_download)print('%s下载完成!用了%d秒'%(filename,time_to_download))defmain2():start=time()p1=Process(target=download_task,args=("Python从入院到住院.pdf",))p1.start()p2=Process(target=download_task,args=("PekingHot.avi",))p2.start()p1.join()p2.join()end=time()print('%.2fsecondsspentintotal.'%(end-start))if__name__=='__main__':main2()执行结果开始下载Pythonfromentrytohospitalization.pdf。..开始下载PekingHot.avi...Python从入门到住院.pdf下载完成!下载PekingHot.avi用了6秒!耗时10秒,一共耗时10.17秒。不再是两个任务的时间总和。知识点流程:通过Process类创建流程对象。target:通过target参数传入一个函数名,表示进程启动后要执行的代码。参数列表start:Process的start()方法,启动进程join:Process的join()方法,意思是等待进程执行结束,再执行Python中的多线程面向对象封装multi的更好实现-threading#!/usr/bin/envpython#-*-coding:utf-8-*-"""__title__=__Time__=2021/3/1918:17__Author__=小菠萝测试笔记__Blog__=https://www.cnblogs.com/poloyy/"""fromrandomimportrandintfromthreadingimportThreadfromtimeimporttime,sleepdefdownload_task(filename):print('开始下载%s...'%filename)time_to_download=randint(5,10)sleep(下载时间)print('%s下载完成!用了%d秒'%(filename,time_to_download))defmain3():start=time()p1=Thread(target=download_task,args=("Python从入院到住院.pdf",))p1.start()p2=Process(target=download_task,args=("PekingHot.avi",))p2.start()p1.join()p2.join()end=time()print('Ittook%.2fsecondsintotal.'%(end-start))if__name__=='__main__':main3()执行结果开始下载Python从入口到hospitalization.pdf...开始下载PekingHot.avi...PekingHot.avi下载完成!Python从入院到住院只用了6秒。PDF下载完成!耗时8秒,一共耗时8.01秒。执行效率也高很多自定义线程类#!/usr/bin/envpython#-*-coding:utf-8-*-"""__title__=__Time__=2021/3/1918:17__Author__=小菠萝测试笔记__Blog__=https://www.cnblogs.com/poloyy/"""fromrandomimportrandintfromthreadingimportThreadfromtimeimporttime,sleepclassdownLoadTask(Thread):def__init__(self,filename):super().__init__()self.filename=filenamedefrun(self)->None:print('开始下载%s...'%self.filename)time_to_download=randint(5,10)sleep(time_to_download)print('%s下载完成!用了%d秒'%(self.filename,time_to_download))defmain3():start=time()p1=downLoadTask("Python从入院到住院.pdf")p2=downLoadTask("PekingHot.avi")p1.start()p2.start()p1.join()p2.join()end=time()print('总共用了%.2f秒。'%(end-start))if__name__=='__main__':main3()执行结果开始下载Python从入门到住院.pdf...开始下载PekingHot.avi...PekingHot.avi下载完成!从入院到住院用了6秒Python。PDF下载完成!耗时9秒,共计9.00秒。也和高效运行的关键知识一样:启动方式和运行方式的区别。startrun函数启动线程,获取运行线程指定的CPU时间片CodeBlockThreadStateRunnableStateRunningStateNumberofCalls一个线程只能调用一次,可以重复调用。运行线程创建一个子线程,线程名由自己命名。在主线程中调用一个公共函数。注意,如果要使用多线程,必须调用start()Python中的协程什么是协程在Python中,单线程+异步I/O编程模型协程的优点是执行效率极高。子程序切换不是线程切换,而是由程序自己控制的。没有线程切换开销,不需要多线程机制。只有一个线程,所以不存在同时写变量的冲突。协程中不需要对共享资源加锁,只需要判断状态,执行效率比多线程高很多。关键是要充分利用CPU的多核特性。应该使用多进程+协程的方式进行更新。EOF本文作者:小菠萝测试笔记本
