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