一.守护线程
非守护线程:如果一个进程有多个线程,程序不会主线程结束后就结束,而是在所有线程都结束才结束
守护线程:主线程结束,子线程结束
def download(url):
time.sleep(3)
print(url, '结束')
if __name__ == '__main__':
t1 = Thread(target=download, args=('阿康的救赎',))
t2 = Thread(target=download, args=('阿康别急',))
# 添加守护线程
t1.setDaemon(True)
t2.setDaemon(True)
t1.start()
t2.start()
print('主线程结束')
二.数据冲突
数据冲突:一般发生在多个线程对同一个数据进行操作的时候
from threading import Thread
data = 0
def up_data():
global data
for _ in range(100008):
data += 1
def down_data():
global data
for _ in range(100008):
data -= 1
if __name__ == '__main__':
# 情况1:在一个线程中对同一个数据进行加减操作
# up_data()
# down_data()
# print(data)
# 情况2:在两个线程中进行加减操作
t1 = Thread(target=up_data)
t2 = Thread(target=down_data)
t1.start()
t2.start()
t1.join()
t2.join()
print(data)
三.手动lock加锁
Lock - 锁类,传统锁,重量级锁(加锁和解锁需要手动进行)
1.创建锁类对象(有多少个数据就创建多少个锁)
data_lock = Lock()
def up_data():
global data
for x in range(100000):
# 2.枷锁
data_lock.acquire()
data +=1
# 3.解锁
data_lock.release()
def down_data():
global data
for _ in range(100000):
data_lock.acquire()
data -= 1
data_lock.release()
if __name__ == '__main__':
t1 = Thread(target=up_data)
t2 = Thread(target=down_data)
t1.start()
t2.start()
t1.join()
t2.join()
print(data)
四.自动锁Rlock
# 1 创建锁
data_lock = RLock()
def up_data():
global data
for x in range(100000):
# 2 使用锁
with data_lock:
data +=1
def down_data():
global data
for _ in range(100000):
with data_lock:
data -= 1
if __name__ == '__main__':
t1 = Thread(target=up_data)
t2 = Thread(target=down_data)
t1.start()
t2.start()
t1.join()
t2.join()
print(data)
五 多进程
需要其他进程的时候就创建进程类Process的对象
注意:不能直接在一个进程中去修改另外一个进程中的数据
def download(url):
print(f'{url}开始下载')
time.sleep(2)
print(f'{url}下载结束')
if __name__ == '__main__':
p1 = Process(target=download, args=('待宰的羔羊',))
p2 = Process(target=download, args=('案板上的鱼肉',))
p1.start()
p2.start()
六 进程间通信
# 支持多进程间通信
from multiprocessing import Process, Queue
def download(url, q):
print(f'{url}开始下载')
time.sleep(2)
print(f'{url}下载结束')
q.put(f'{url}电影')
if __name__ == '__main__':
q = Queue()
p1 = Process(target=download, args=('待宰的羔羊', q))
p2 = Process(target=download, args=('案板上的鱼肉', q))
p1.start()
p2.start()
print('================')
print(q.get())
print(q.get())
七 进程池
if __name__ == '__main__':
# 1.创建进程池对象
pool = Pool(3)
# 2.添加任务和执行任务(添加后会自动执行)
# 1) 同时添加多个任务
params = list(range(10))
all_data = pool.map(calculate, params)
other_data = pool.map(other_task, params)
print(all_data,other_data)
# 2)添加一个任务
one_data = pool.apply(calculate, (-20,))
print(one_data)
# 3.关闭进程池(停止往进程池中添加任务;进程池在没有关闭的时候可以随时添加新的任务)
pool.close()
# 4.等待进程池中的任务都结束
pool.join()