一 先谈一下什么是进程,与线程的区别
第一:
进程是cpu资源分配的最小单元。
线程是cpu计算的最小单元。
第二:
一个进程中可以有多个线程。
第三:
对于Python来说他的进程和线程和其他语言有差异,是有GIL锁。
GIL锁保证一个进程中同一时刻只有一个线程被cpu调度。
注意:IO密集型操作可以使用多线程;计算密集型可以使用多进程;
二 面向对象的补充
class Foo(object): def __init__(self): object.__setattr__(self, 'info', {}) # 在对象中设置值的本质,主动调用,是函数需要自己传参(self) def __setattr__(self, key, value): self.info[key] = value def __getattr__(self, item): print(item) return self.info[item] obj = Foo() obj.name = 'alex'#其实是默认执行__setattr__方法,自己没有找父类.而平时我们都没有写,都去找父类执行了 print(obj.name)
class Foo(object): def __init__(self): self.info = {} def __setitem__(self, key, value): self.info[key] = value def __getitem__(self, item): return self.info.get(item) obj = Foo() obj['x'] = 123
三 进程的特点,进程间数据不共享,举个例子
data_list = [] def task(arg): data_list.append(arg) print(data_list) def run(): for i in range(10): p = multiprocessing.Process(target=task,args=(i,)) # p = threading.Thread(target=task,args=(i,)) p.start() if __name__ == '__main__': run() #结果是[0],[1],[2],[3]....
四 进程的一些常见属性
# import time # from multiprocessing import Process # # def f(name): # print('hello', name) # time.sleep(3) # print('我是子进程') # # # if __name__ == '__main__': # p = Process(target=f, args=('bob',)) # p.start() # #p.join() # print('我是父进程') # 我是父进程 # hello bob # 我是子进程
getpid 和 getppid
# import os # from multiprocessing import Process # # def f(x): # print('子进程id :',os.getpid(),'父进程id :',os.getppid()) # return x*x # # if __name__ == '__main__': # print('主进程id :', os.getpid()) # for i in range(5): # p = Process(target=f, args=(i,)) # p.start() # #主进程id : 7856 # 子进程id : 3424 父进程id : 3424 # 子进程id : 2360 父进程id : 2360 # 子进程id : 5188 父进程id : 5188 # 子进程id : 364 父进程id : 364 # 子进程id : 860 父进程id : 860
进阶,多个进程同时运行(注意,子进程的执行顺序不是根据启动顺序决定的)
# import time # from multiprocessing import Process # # # def f(name): # time.sleep(3) # print('hello', name) # # # # if __name__ == '__main__': # p_lst = [] # for i in range(5): # p = Process(target=f, args=('bob',)) # p.start() # p_lst.append(p) # p.join(2) # # print('父进程在执行')# 这个速度相当慢 # # # import time # from multiprocessing import Process # # # def f(name): # print('hello', name) # time.sleep(2) # # # if __name__ == '__main__': # p_lst = [] # for i in range(5): # p = Process(target=f, args=('bob',)) # p.start() # p_lst.append(p) # for i in p_lst: # i.join() # # print('父进程在执行') #这个速度快
import time,os from multiprocessing import Process def f(name): print('hello', name) time.sleep(2) if __name__ == '__main__': p_lst = [] for i in range(5): p = Process(target=f, args=('bob',)) p.start() print(p.pid) #这个值当前线程的ip,变化 print(os.getpid())#主线程的IP 每次运行不会发生变化 p_lst.append(p) for i in p_lst: i.join() # print('父进程在执行') #这个速度快
name,和获取当前线程
import time,multiprocessing def task(arg): name1 = multiprocessing.current_process() #获取当前进程
name = name1.name#获取当前进程名字 print(name1,"888") time.sleep(2) print(arg) def run(): print('111111111') p1 = multiprocessing.Process(target=task,args=(1,)) p1.name = 'pp1' #设置进程的名字 p1.start() print('222222222') p2 = multiprocessing.Process(target=task, args=(2,)) p2.name = 'pp2' #给当前进程设置名字,和线程的区别,没有set(线程是p.set_name= ...) p2.start() print('333333333') if __name__ == '__main__': run() # #111111111 # 222222222 # 333333333 # pp1 888 # pp2 888 # 1 # 2
from multiprocessing import Process def foo(): print(123) time.sleep(1) print("end123") def bar(): print(456) time.sleep(3) print("end456") def run(): p1=Process(target=foo) p2=Process(target=bar) p1.daemon=True p1.start() p2.start() time.sleep(0.1) print("main-------")#打印该行则主进程代码结束,则守护进程p1应该被终止.#可能会有p1任务执行的打印信息123,因为主进程打印main----时,p1也执行了,但是随即被终止. if __name__ == '__main__': run() 结果是没有打印123 main------- 456 end456
四 进程数据共享的方法
import multiprocessing import threading import queue import time q = multiprocessing.Queue() #q = queue.Queue() #这个是不行的 def task(arg): q.put(arg) def run(): for i in range(10): p = multiprocessing.Process(target=task, args=(i, )) p.start() while True: v = q.get() print(v) # 1 2 3 4 5 6 7 8 9 if __name__ == '__main__': run() # def task(arg, q): # q.put(arg) # # # if __name__ == '__main__': # q = multiprocessing.Queue() # for i in range(10): # p = multiprocessing.Process(target=task, args=(i, q,)) # p.start() # while True: # v = q.get() # print(v) # 0 1 2 3 4 5 6 7 8 9
#linux 系统 q = multiprocessing.Queue() def task(arg,q): q.put(arg) def run(): for i in range(10): p = multiprocessing.Process(target=task, args=(i, q,)) p.start() while True: v = q.get() print(v) run()
def task(arg,dic): dic[arg] = 100 def run(dic): for i in range(10): p = multiprocessing.Process(target=task, args=(i,dic)) p.start() p.join() input('>>>') print(dic.values()) if __name__ == '__main__': m = multiprocessing.Manager() dic = m.dict() run(dic)
如果是普通的字典,不会发生数据共享
import time def task(arg, dic): time.sleep(2) dic[arg] = 100 print(dic) if __name__ == '__main__': m = multiprocessing.Manager() dic ={} process_list = [] for i in range(10): p = multiprocessing.Process(target=task, args=(i, dic,)) p.start() p.join() print(dic) # {0: 100} # {1: 100} # {2: 100} # {3: 100} # {4: 100} # {5: 100} # {6: 100} # {7: 100} # {8: 100} # {9: 100} # {} #普通的字典数据不共享
五
进程锁和线程锁是一样的(五种),设置进程锁,同样是为了维护数据的安全
六 进程也有继承类的编写方发
class MyProcess(multiprocessing.Process): def run(self): print('当前进程',multiprocessing.current_process()) def run(): p1 = MyProcess() p1.start() p2 = MyProcess() p2.start() if __name__ == '__main__': run()
七 进程池
import time from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor def task(arg): time.sleep(2) print(arg) if __name__ == '__main__': pool = ProcessPoolExecutor(5) for i in range(10): pool.submit(task,i)
八 自己编写的Manger
import multiprocessing def task(arg, dic): # time.sleep(2) dic[arg] = 100 if __name__ == '__main__': m = multiprocessing.Manager() dic = m.dict() process_list = [] for i in range(10): p = multiprocessing.Process(target=task, args=(i, dic,)) p.start() process_list.append(p) while True: count = 0 for p in process_list: if not p.is_alive(): count += 1 if count == len(process_list): break print(dic) import multiprocessing def task(arg,dic): dic[arg]="100" def run(): m = multiprocessing.Manager() dic = m.dict() process_list = [] for i in range(5): p = multiprocessing.Process(target=task,args = (i,dic)) p.start() # p.join() process_list.append(p) n =0 while 1: for i in process_list: if not i.is_alive(): n+=1 if n == len(process_list): break print(dic) if __name__ == '__main__': run()
九 自己编写的multiprocessing.queue
import multiprocessing def task(arg,q): q.put(arg) def run(): q = multiprocessing.Queue() for i in range(5): p = multiprocessing.Process(target= task,args = (i,q)) p.start() while 1: print(q.get()) if __name__ == '__main__': run()