目录
1.进程
1.进程的创建
1.进程就是程序执行的载体
2.打开的每个程序,每个python脚本都是启动一个进程;
3.进程的运行就是cpu和内存
4.多进程就是同时执行多个程序
5. 进程的创建: multiprocessing模块
6.多线程的问题:
1.通过多线程执行的模块无法获取返回值;(可以通过进程池获取)
2.多个进程修改文件可能会出现问题;(可以使用进程锁解决)
3.进程数量太多可能会照成资源不足,系统宕机;
import os import time import multiprocessing def work_a(): for i in range(5): print(i,"a","pid:",os.getpid()) time.sleep(1) def work_b(): for i in range(5): print(i,"b","pid:",os.getpid()) time.sleep(1) if __name__ == '__main__': nowtime=time.time() workaPrcess=multiprocessing.Process(target=work_a) workbPrcess = multiprocessing.Process(target=work_b) for i in (workaPrcess,workbPrcess): i.start() for i in (workaPrcess, workbPrcess): i.join() print("执行时间:" , time.time()-nowtime) print("主线程pid:", os.getpid())>
0 a pid: 77024
0 b pid: 76972
1 a pid: 770241 b
pid: 76972
22 ba pid:pid: 77024769723 3b pid:a 76972pid: 77024
4 a pid: 77024
4 b pid: 76972
执行时间: 5.307990789413452
主线程pid: 79928
2.进程池和进程锁
1.进程池为了避免进程创建过多,照成系统资源不足,可以设置固定数量的进程池;
2.避免了创建与关闭的消耗;
3.进程池的创建 multiprocessing
4.可以获取返回值
import os import time import multiprocessing def printcount(count): print("count: {} pid: {}".format(count,os.getpid())) time.sleep(1) return count,os.getpid() if __name__ == '__main__': #声明5个进程池 pool = multiprocessing.Pool(5) results=[] for i in range(20): result=pool.apply_async(func=printcount,args=(i,)) results.append(result) for res in results: print("进程返回参数:{}".format(res.get()))
3.进程锁
1.进程锁的创建 ,同样可用于线程锁;
2.用于进程之间的阻塞
import os import time import multiprocessing def printcount(count,lock): try: lock.acquire() print("count: {} pid: {}".format(count,os.getpid())) time.sleep(1) return count,os.getpid() finally: lock.release() if __name__ == '__main__': #声明5个进程池 pool = multiprocessing.Pool(5) results=[] #添加锁,每个进程进行阻塞 manage= multiprocessing.Manager() lock=manage.Lock() for i in range(20): result=pool.apply_async(func=printcount,args=(i,lock,)) results.append(result) for res in results: print("进程返回参数:{}".format(res.get()))
4.进程的通信
1. 进程之前的通信依赖于队列,
2. 队列的创建
import multiprocessing import time class Work(object): def __init__(self,q): self.q=q def send(self,message): self.q.put(message) def receive(self): while True: print("接受到值",self.q.get()) def sendall(self): i=0 while True: i += 1 self.q.put(i) time.sleep(1) if __name__ == '__main__': work=Work(multiprocessing.Queue()) send=multiprocessing.Process(target=work.send,args=("你好",)) send.start() receive=multiprocessing.Process(target=work.receive) receive.start() sendall = multiprocessing.Process(target=work.sendall) sendall.start() sendall.join()
2.线程
1.线程依赖于进程,现有进程才有拥有线程;通过进程的资源来执行任务
2. 一个进程总存在多个线程,称为多线程
3.正常执行的脚本就是主线程,
1.线程的创建
1.线程的问题:
1. 通过线程执行的函数无法获取返回值
2.多线程同时修改文件可能会照成数据错乱
import threading import random import time ''' 通过多线程,进行将一个list数据存放到另一个list中 ''' old_list=["1","2","3","4","5","6","7","8","9"] new_list=[] def work(): #通过随机函数,随机获取放入到新list中 item=random.choice(old_list) old_list.remove(item) new_list.append(item) #模拟数据执行,防止执行太快 time.sleep(1) if __name__ == '__main__': threads=[] nwotime=time.time() for i in range(len(old_list)): thread=threading.Thread(target=work) thread.setName("work-th") thread.start() threads.append(thread) for thread in threads: thread.join() print("old_list:",old_list) print("new_list:", new_list) print("执行时间:",(time.time()-nwotime))old_list: []
new_list: ['7', '5', '6', '9', '2', '3', '8', '4', '1']
执行时间: 1.0147948265075684
2.线程次的创建
from concurrent.futures import ThreadPoolExecutor import time from multiprocessing import Manager def work(i,lock): lock.acquire() try: print("i:",i) time.sleep(1) return i finally: lock.release() if __name__ == '__main__': tPool= ThreadPoolExecutor(2) threads=[] #添加锁阻塞线程 lock=Manager().Lock() for i in range(20): thread=tPool.submit(work,i,lock) threads.append(thread) for thread in threads: print(thread.result())
3.Gil全局锁
1. 在python中保留的Gil锁,
2.在其他语言中,主进程会自动寻找空闲的线程;
3.在python中定义了一个进程,只会在一个线程中执行,不会寻找有空闲的线程执行;
1. python的多线程只会在一个线程中执行
2.为了保留线程的安全
3.可以使用pypy可去掉Gil线程锁
4.可以通过多进程和多线程解决
4.异步的使用
1. 异步与多线程多进程的区别
1.异步也是一个线程,属于轻量级的线程;“协程”
2.可以通过异步获取返回值;
3.主进程需要异步才行,所有程序都是异步才可进行执行;
4.更适合与文件的读写使用;
2.async定义异步
3.await 执行异步
4.asyncio调用async函数,在web开发中不用考虑,在窗口联系中需要使用这个;
5.gevent异步使用