python3 多任务————进程
一、进程和程序
计算机程序只是存储在磁盘上的可执行的二进制(或者其他类型)文件;只有把它们加载到内存中并被操作系统调用,才拥有其生命期。
进程(有时候称为重量级进程)则是一个执行中的程序,每个进程都拥有自己的地址空间,内存,数据栈以及其它用于跟踪执行的辅助数据;操作系统管理其上的所有进程的执行,并为这些线程合理地分配时间。
通俗来讲,程序是死的,是静态的(存储在磁盘上面的二进制文件,如xxx.py);
进程就是一个程序运行起来,代码+用到的资源(内存,硬盘,显示器,网络。。。。)称之为进程,它是操作系统分配资源的基本单元。进程也是实现多任务的方式之一。

使用进程完成多任务:
__author__ = 'Administrator' import multiprocessing def test1(): for i in range(10): print("========%d====" %i) def test2(): for i in range(10): print("========%d====" %i) def main(): p1=multiprocessing.Process(target=test1) p2=multiprocessing.Process(target=test2) p1.start() p2.start() if __name__ == '__main__': main() #################### ========0==== ========1==== ========2==== ========3==== ========4==== ========5==== ========6==== ========7==== ========8==== ========9==== ========0==== ========1==== ========2==== ========3==== ========4==== ========5==== ========6==== ========7==== ========8==== ========9====
二、进程和线程的区别:——面试题
1.功能:
进程——能够完成多任务,比如在电脑上能够打开多个微信;
线程——能够完成多任务,比如在电脑上打开的微信的微信多个聊天窗口;
【在进程里面实现多任务,这就是线程,进程先有才有线程,其实进程仅仅只是个资源分配的单位,线程拿着进程资源去实现多任务。一个进程里至少有一个主线程。进程之间是独立的】
2.定义的不同
进程是系统进行资源分配和调度的一个独立单位;
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
3.区别
一个程序至少有一个进程,一个进程至少有一个线程;
线程的划分尺度小于进程(资源比进程少),使得多线程程序的并发性高;
进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率 ;
线程不能够独立执行,必须依存在进程中。
4.优缺点:
线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程正相反。
5.通过队列完成进程间的通信:
队:先进先出
栈:先进后出
【通过队列可以解耦合】
__author__ = 'Administrator' import multiprocessing def download_from_web(q): #模拟从网上下载的数据 data=[11,22,33,44,55,66] # 向队列中写入数据 for temp in data: q.put(temp) print("数据已经下载完成了。。。。。") def analysis_data(q): """数据处理""" all_data=list() # 从队列中获取数据 while True: data=q.get() all_data.append(data) # 模拟数据处理 if q.empty(): break print("数据处理完毕。。。。。") def main(): # 1.创建一个队列 q=multiprocessing.Queue() # 2.创建多个进程,将队列的引用当做实参进行传递到里面 t1=multiprocessing.Process(target=download_from_web,args=(q,)) t2=multiprocessing.Process(target=analysis_data,args=(q,)) t1.start() t2.start() if __name__ == '__main__': main()
6.进程池:[涉及到回调函数,callback]
__author__ = 'Administrator' from multiprocessing import Pool import os,time,random def task(msg): print("start....") t_start=time.time() # os.getpid()获取当前进程id os.getppid()获取父进程id print("%s开始执行,进程号为%d" %(msg, os.getpid())) # random.random()随机生成0到1之间的浮点数 time.sleep(random.random()*2) t_stop=time.time() print("%s执行结束,耗时为%0.2f" %(msg, t_stop - t_start)) return (msg, os.getpid(), t_stop - t_start) def call_back(result): print(result) def main(): # 定义一个进程池,最大进程数为3 po=Pool(3) for i in range(0,10): # 每次循环将会用空闲出来的子进程去调用目标 po.apply_async(task,(i,), callback=call_back) print("——————开始啦!!——————") # 关闭进程池,关闭后po不在接收新的请求 po.close() # 等待po中所有的子进程执行完成,必须放在close语句后面 po.join() print("——————结束啦!!——————") if __name__ == '__main__': main() ######################################## ——————开始啦!!—————— start.... 0开始执行,进程号为7600 start.... 1开始执行,进程号为6164 start.... 2开始执行,进程号为2428 1执行结束,耗时为1.07 0执行结束,耗时为1.08 start.... 3开始执行,进程号为6164 (1, 6164, 1.0667860507965088) (0, 7600, 1.0752921104431152) start.... 4开始执行,进程号为7600 2执行结束,耗时为1.27 start.... (2, 2428, 1.270904779434204) 5开始执行,进程号为2428 3执行结束,耗时为0.49 start.... 6开始执行,进程号为6164 (3, 6164, 0.4923520088195801) 5执行结束,耗时为0.42 start.... 7开始执行,进程号为2428 (5, 2428, 0.42132115364074707) 4执行结束,耗时为1.20 (4, 7600, 1.2017979621887207) start.... 8开始执行,进程号为7600 8执行结束,耗时为0.33 (8, 7600, 0.3322930335998535) start.... 9开始执行,进程号为7600 7执行结束,耗时为1.38 (7, 2428, 1.3759560585021973) 6执行结束,耗时为1.64 (6, 6164, 1.6431488990783691) 9执行结束,耗时为1.24 (9, 7600, 1.238882064819336) ——————结束啦!!——————
7.文件夹copy器:
__author__ = 'Administrator' import os import multiprocessing #from multiprocessing import Manager,Pool def copy_file(q,file_name,old_foloder_name,new_foloder): """完成文件的copy""" old_f=open(old_foloder_name+"/"+file_name,"rb") content_old=old_f.read() old_f.close() new_f=open(new_foloder+"/"+file_name,"wb") new_f.write(content_old) new_f.close() # 如果copy完了文件,那么就向队列中写入一个消息,表示已经完成 q.put(file_name) def main(): # 1.获取用户想要copy的文件夹的名字 old_foloder_name=input("请输入想要copy的文件夹名字:") # 2.创建一个新的文件夹 try: new_foloder_name="新—"+old_foloder_name os.mkdir(new_foloder_name) except: pass # 3.获取文件夹的所有的待copy的文件名字 listdir() file_names=os.listdir(old_foloder_name) print(file_names) # 4.创建进程池 po=multiprocessing.Pool(5) # 5.创建一个队列 q=multiprocessing.Manager().Queue() # 5.向进程池中添加copy文件的任务 for file_name in file_names: po.apply_async(copy_file,args=(q,file_name,old_foloder_name,new_foloder_name)) po.close() # po.join() all_file=len(file_names) while True: file_name=q.get() copy_ok_num=0 print("已经完成copy:%s" %file_name) print("\r copy的进度条:%.2f %%" %(copy_ok_num*100/all_file),end="") copy_ok_num+=1 if copy_ok_num>all_file: break if __name__ == '__main__': main()

浙公网安备 33010602011771号