多任务的执行方式
进程
概念
python多进程
- Windows下的main判断
- process进程类
1. import multiprocessing 2. import time 3. def sing(): 4. for i in range(3): 5. print(f"唱歌第{i}次") 6. time.sleep(0.2) 7. def dance(): 8. for i in range(3): 9. print(f"跳舞第{i}次") 10. time.sleep(0.2) 11. if __name__ == '__main__': 12. sing_pro = multiprocessing.Process(target=sing) 13. dance_pro = multiprocessing.Process(target=dance) 14. sing_pro.start() 15. dance_pro.start()
注:此时唱歌和跳舞的优先度由系统调度决定(随机)
- 获取进程id
1. import multiprocessing 2. import time 3. import os 4. def sing(): 5. print('sing的父进程id:',os.getppid()) 6. for i in range(3): 7. print(f"唱歌第{i}次") 8. time.sleep(1) 9. os.kill(os.getpid(),9) 10. # 强制结束进程 11. def dance(): 12. for i in range(3): 13. print(f"跳舞第{i}次") 14. time.sleep(1) 15. if __name__ == '__main__': 16. sing_pro = multiprocessing.Process(target=sing) 17. dance_pro = multiprocessing.Process(target=dance) 18. print("sing:", sing_pro) 19. print("dance:", dance_pro) 20. sing_pro.start() 21. dance_pro.start() 22. print("main:",os.getpid(),multiprocessing.current_process())
sing: <Process name='Process-1' parent=5920 initial>
dance: <Process name='Process-2' parent=5920 initial>
main: 5920 <_MainProcess name='MainProcess' parent=None started>
跳舞第0次
sing的父进程id: 5920
唱歌第0次
跳舞第1次
跳舞第2次
- 带参任务的执行
1. import multiprocessing 2. def show(name,age): 3. print(f"姓名:{name},年龄是{age}岁") 4. if __name__ == '__main__': 5. show_pro1=multiprocessing.Process(target=show("coleak1",19)) 6. show_pro2=multiprocessing.Process(target=show,args=('coleak2',20)) 7. show_pro3=multiprocessing.Process(target=show,kwargs={"age":21,"name":'coleak3'}) 8. show_pro1.start() 9. show_pro2.start() 10. show_pro3.start()
姓名:coleak1,年龄是19岁
姓名:coleak2,年龄是20岁
姓名:coleak3,年龄是21岁
- 注意点
- 进程间全局变量不共享
- 主进程会等待所有子进程执行结束后再结束
- 进程之间执行是无序的,由操作系统调度决定
1. import multiprocessing 2. import time 3. import multiprocessing 4. my_list=list() 5. def add(): 6. for i in range(3): 7. my_list.append(i) 8. print("add:",i) 9. time.sleep(0.5) 10. print(my_list) 11. def read(): 12. print("read:",my_list) 13. if __name__ == '__main__': 14. p1 = multiprocessing.Process(target=add) 15. p2 = multiprocessing.Process(target=read) 16. p1.start() 17. p1.join() 18. #当前进程等待p1进程执行结束后再执行 19. p2.start() 20. print("main:",my_list)
add: 0
add: 1
add: 2
[0, 1, 2]
main: []
read: []
1. import multiprocessing 2. import time 3. def test(): 4. for i in range(6): 5. print(i) 6. time.sleep(0.2) 7. if __name__ == '__main__': 8. p1=multiprocessing.Process(target=test) 9. p1.start() 10. time.sleep(0.5) 11. print('over!')
0
1
2
over!
3
4
5
- 主进程退出,子进程销毁
1. import multiprocessing 2. import time 3. def test(): 4. while True: 5. print('执行ing...') 6. time.sleep(0.2) 7. if __name__ == '__main__': 8. p1=multiprocessing.Process(target=test) 9. p1.daemon=True 10. # 子进程守护主进程 11. p1.start() 12. time.sleep(0.5) 13. print('over!')
执行ing...
执行ing...
执行ing...
over!
1. import multiprocessing 2. import time 3. def test(): 4. while True: 5. print('执行ing...') 6. time.sleep(0.2) 7. if __name__ == '__main__': 8. p1=multiprocessing.Process(target=test,name='coleak') 9. p1.start() 10. time.sleep(0.5) 11. p1.terminate() 12. print('over!')
执行ing...
执行ing...
执行ing...
over!
线程
概念
python多线程
1. import threading 2. import time 3. def sing(): 4. for i in range(3): 5. print(f"唱歌第{i}次") 6. time.sleep(0.2) 7. def dance(): 8. for i in range(3): 9. print(f"跳舞第{i}次") 10. time.sleep(0.2) 11. if __name__ == '__main__': 12. t1=threading.Thread(target=sing) 13. t2=threading.Thread(target=dance) 14. t1.start() 15. t2.start()
唱歌第0次跳舞第0次
唱歌第1次跳舞第1次
唱歌第2次跳舞第2次
1. import threading 2. import time 3. def test(): 4. t=threading.current_thread() 5. print('test:',t) 6. 7. if __name__ == '__main__': 8. print("main:",threading.current_thread()) 9. t1=threading.Thread(target=test) 10. t1.start()
main: <_MainThread(MainThread, started 3100)>
test: <Thread(Thread-1 (test), started 10836)>
- 带参任务
同进程知识点
- 注意点
- 线程之间执行是无序的,由cpu调度决定
- 主线程等子线程结束后再结束
- 线程之间共享全局变量
- 线程之间共享全局变量数据会出错
1. import threading 2. import time 3. def test(): 4. time.sleep(1) 5. print(threading.current_thread()) 6. if __name__ == '__main__': 7. for i in range(20): 8. t=threading.Thread(target=test) 9. t.start()
- demon守护主进程
1. import threading 2. import time 3. def test(): 4. while True: 5. print('执行ing...') 6. time.sleep(0.2) 7. if __name__ == '__main__': 8. p1=threading.Thread(target=test,daemon=True) 9. p1.start() 10. time.sleep(0.5) 11. print('over!')
1. import threading 2. import time 3. def test(): 4. while True: 5. print('执行ing...') 6. time.sleep(0.2) 7. if __name__ == '__main__': 8. p1=threading.Thread(target=test) 9. p1.setDaemon(True) 10. p1.start() 11. time.sleep(0.5) 12. print('over!')
执行ing...
执行ing...
执行ing...
over!
1. import threading 2. import time 3. def test(): 4. for i in range(3): 5. my_list.append(i) 6. print("add:",i) 7. if __name__ == '__main__': 8. my_list = list() 9. p1=threading.Thread(target=test) 10. p1.start() 11. time.sleep(1) 12. print(my_list)
add: 0
add: 1
add: 2
[0, 1, 2]
1. import threading 2. import time 3. a=0 4. def test1(): 5. global a 6. for i in range(1000000): 7. a+=1 8. def test2(): 9. global a 10. for i in range(1000000): 11. a+=1 12. if __name__ == '__main__': 13. p1=threading.Thread(target=test1) 14. p2=threading.Thread(target=test2) 15. p1.start() 16. p2.start() 17. print(a)
993031,和正确结果相差了近7000
线程同步方式
线程等待
- join
互斥锁
- 概念
- 使用
1. import threading 2. import time 3. a=0 4. lock=threading.Lock() 5. def test1(): 6. lock.acquire() 7. for i in range(1000000): 8. global a 9. a+=1 10. # print(a) 11. lock.release() 12. def test2(): 13. lock.acquire() 14. for i in range(1000000): 15. global a 16. a+=1 17. # print(a) 18. lock.release() 19. if __name__ == '__main__': 20. p1=threading.Thread(target=test1) 21. p2=threading.Thread(target=test2) 22. p1.start() 23. p2.start() 24. time.sleep(2) 25. print(a,'over')
2000000 over
死锁
1. import threading 2. import time 3. lock=threading.Lock() 4. def get(index): 5. my_list=[6,5,8,7] 6. lock.acquire() 7. if index>=len(my_list): 8. print("下标越界",index) 9. return 10. print(my_list[index]) 11. lock.release() 12. 13. if __name__ == '__main__': 14. for i in range(10): 15. p=threading.Thread(target=get,args=(i,)) 16. p.start()
6
5
8
7
下标越界 4
- 改进方案
1. import threading 2. import time 3. lock=threading.Lock() 4. def get(index): 5. my_list=[6,5,8,7] 6. lock.acquire() 7. if index>=len(my_list): 8. print("下标越界",index) 9. lock.release() 10. return 11. print(my_list[index]) 12. lock.release() 13. 14. if __name__ == '__main__': 15. for i in range(10): 16. p=threading.Thread(target=get,args=(i,)) 17. p.start()
6
5
8
7
下标越界 4
下标越界 5
下标越界 6
下标越界 7
下标越界 8
下标越界 9
线程和进程对比