多线程
参考 :https://docs.python.org/zh-cn/3.7/library/threading.html
文章目录
明确一下
- 当没有存活的非守护线程时,整个Python程序才会退出。(多进程也一样)
先来个简单的多线程
import threading
import os, time, random
def loop():
print('child start:', threading.current_thread().name)
n = 0
while n < 5:
n += 1
print(threading.current_thread().name, n)
time.sleep(1)
print('child end', threading.current_thread().name)
print(threading.current_thread().name)
t = threading.Thread(target=loop)
t1 = threading.Thread(target=loop)
t.start()
t1.start()
t.join()
t1.join()
print('end')
Lock – 遇到临界资源,上锁!
import threading, os, time
lock = threading.Lock()
N = 10
poch = 10000000
def add():
global N
lock.acquire()
for i in range(poch):
N += 1
lock.release()
def desc():
global N
lock.acquire()
for i in range(poch):
N -= 1
lock.release()
def see():
global N
while True:
time.sleep(1)
print(N)
if __name__ == '__main__':
t1 = threading.Thread(target=add)
t2 = threading.Thread(target=desc)
# t3 = threading.Thread(target=see)
# t3.daemon = True
# t3.start()
t1.start()
t2.start()
t1.join()
t2.join()
# t3.join()
print(t1.is_alive())
print(t2.is_alive())
print(N)
condition – 执行结束后唤醒其他线程
threading.Condition()
# 等待 和 唤醒
import threading, time
n = 0
cond = threading.Condition()
def produce():
global n
time.sleep(1)
n += 1
print('produce apple !')
with cond:
cond.notify()
# cond.notify_all() 用来唤醒所有等待的。
def eat_1():
global n
with cond:
while n == 0:
cond.wait()
print('Bob is eatting !')
def eat_2():
global n
with cond:
# wait_for 接受可调用对象,因此用lambda。
cond.wait_for(lambda: n != 0)
print('Mike is eatting !')
t1 = threading.Thread(target=produce)
t2 = threading.Thread(target=eat_1)
t3 = threading.Thread(target=eat_2)
t1.start()
t2.start()
t3.start()
t1.join()
t2.join()
t3.join()
print('main over')
semaphore – 同时只能有2个人吃饭!
通常用来保护有限的资源
使用有界信号量能减少这种编程错误:信号量的释放次数多于其请求次数。
from threading import BoundedSemaphore, Thread
import time
sema = BoundedSemaphore(2)
def eating(person_id):
with sema:
time.sleep(1)
print(person_id, 'eating')
if __name__ == '__main__':
tasks = [Thread(target=eating, args=(pid,)) for pid in range(10)]
[t.start() for t in tasks]
Event – 天亮了,都起床!
简单的通信机制,和condition有点像
import threading
import time
event = threading.Event()
def light():
time.sleep(2)
print('天亮了,都起床!')
event.set()
def p1():
event.wait()
print('p1 yes')
def p2():
event.wait()
print('p2 yes')
if __name__ == '__main__':
p = threading.Thread(target=light)
p1 = threading.Thread(target=p1)
p2 = threading.Thread(target=p2)
p.start()
p1.start()
p2.start()
print('haha')