python调用的是操作系统的原生线程,
表面是多线程,同一时间只有一个线程在运行,我们看到的多线程并发的现象,只是python利用的cpu的上下文切换,
cpu的计算速度很快,所以看起来是并发的效果。
所有如果你的代码是cpu密集型,用单线程比多线程效率可能更高,
如果是io密集型,用多线程的效率就很高了。
不够如果要用python确实的进行多线程,python里面也有折中的方法,需要几个线程就开启几个进程,每个进程里面的线程就可以起到多线程的真实效果。
最简单的python3多线程,代码如下:
import threading
import time
def run(t):
print(t)
time.sleep(1)
t1 = threading.Thread(target=run, args=("t1", ))
t2 = threading.Thread(target=run, args=("t2", ))
t1.start()
t2.start()
用类的方式开启多线程:
import threading
import time
"""
以类的方式启用多线程
"""
class MyThread(threading.Thread):
def __init__(self, n, sleep_time):
super(MyThread, self).__init__()
self.n = n
self.sleep_time = sleep_time
def run(self):
print("task:", self.n)
time.sleep(self.sleep_time)
print("task %s done" % self.n)
t1 = MyThread("t1", 2)
t2 = MyThread("t2", 4)
t1.start()
t2.start()
#等待t1线程执行完毕
t1.join()
print("----main thread----")
开启50个线程,并计算运行时间:
import threading
import time
start_time = time.time()
#创建空列表,存储每个线程对象
t_objs = []
def run(n):
#打印当前运行的线程
print("task, ", n, threading.current_thread())
time.sleep(1)
print("task %s done" % n)
#开启50个线程
for i in range(50):
t = threading.Thread(target=run, args=(i, ))
t.start()
t_objs.append(t)
#等待所有线程执行完毕
for i in t_objs:
t.join()
print("----all thread done----,", threading.current_thread())
print("cost:", time.time() - start_time)
守护线程:
import threading
import time
"""
守护线程
主人死了,仆人殉葬
"""
start_time = time.time()
t_objs = []
def run(n):
#打印当前所在线程
print("task, ", n, threading.current_thread())
time.sleep(1)
print("task %s done" % n)
for i in range(50):
t = threading.Thread(target=run, args=(i, ))
#守护线程,主线程执行完就退出程序,不等子线程
t.setDaemon(True)
t.start()
t_objs.append(t)
#等待所有线程执行完毕再继续主线程
#for i in t_objs:
#t.join()
print("----all thread done----,", threading.current_thread())
print("cost:", time.time() - start_time)
GIL全局锁:
import threading, time
"""
GIL 全局解释器锁
同一时间只有一个线程修改数据
同时修改数据的时候,避免出现差错
"""
def count():
#加锁,每个线程进来都加锁,执行完当前线程之后,下一个线程再进来
lock.acquire()
global num
num += 1
print("curren_thread:", threading.current_thread())
time.sleep(1)
#解锁
lock.release()
num = 0
#申请一把解释器锁
lock = threading.Lock()
t_objs = []
for i in range(50):
t = threading.Thread(target=count)
t.start()
t_objs.append(t)
#子线程全部执行完毕,再继续主线程
for i in t_objs:
i.join()
print("num:", num)
递归全局锁:
import threading, time
"""
递归锁
锁多的时候要用递归锁
避免钥匙搞乱,造成死循环
"""
def run1():
global num1
print("grab the first part data")
lock.acquire()
num1 += 1
lock.release()
return num1
def run2():
global num2
print("grab the second part data")
lock.acquire()
num2 += 1
lock.release()
return num2
def run3():
lock.acquire()
res1 = run1()
print("----between run1 and run2----")
res2 = run2()
lock.release()
print(res1, res2)
lock = threading.RLock()
num1, num2 = 0, 0
t_objs = []
for i in range(10):
t = threading.Thread(target=run3)
t.start()
t_objs.append(t)
for i in t_objs:
i.join()
while threading.active_count() != 1:
print(threading.active_count())
else:
print("all threads done")
print(num1, num2)
BoundedSemaphore信号量:
import threading, time
def run(m):
semaphore.acquire()
print("task ", m)
time.sleep(1)
m += 1
semaphore.release()
#设置信号量为5,最多允许5个线程同时运行
semaphore = threading.BoundedSemaphore(2)
for i in range(10):
t = threading.Thread(target=run, args=(i, ))
t.start()
while threading.active_count() != 1:
pass
else:
print("all threads done")
queue队列:
import queue, threading, time
"""
队列:
queue.Queue() 先进先出
queue.FiloQueue() 先进后出
queue.PrioriteQueue() 设置队列优先级
qsize() 打印队列大小
"""
q = queue.Queue(maxsize=10)
#生产者
def producer(name):
count = 0
while True:
print("[%s]生产了骨头[%s]" % (name, count))
q.put(count)
count += 1
time.sleep(2)
#消费者
def consumer(name):
while True:
print("[%s]吃了骨头[%s]..." % (name, q.get()))
time.sleep(3)
p1 = threading.Thread(target=producer, args=("小白", ))
c1 = threading.Thread(target=consumer, args=("鹿晗", ))
c2 = threading.Thread(target=consumer, args=("皮几万", ))
p1.start()
c1.start()
c2.start()
event事件:
import threading, time
"""
event事件
功能类似于标志位
设置了事件线程可以通过,
清楚设置为线程不能通过
"""
def lighter():
counter = 0
event.set()
while True:
if counter > 5 and counter < 12:
#清除标志位,阻塞,红灯
event.clear()
print("\033[41;1mred light is on...\033[0m")
elif counter > 12:
#设置标志位,放行,绿灯
event.set()
counter = 0
else:
print("\033[42;1mgreen light is on...\033[0m")
time.sleep(1)
counter += 1
def car(name):
while True:
#绿灯
if event.is_set():
print("[%s] run!" % name)
time.sleep(1)
else:
print("[%s] sees red light, waiting...." % name)
event.wait()
print("[%s] sees green light, start going...." % name)
event = threading.Event()
lighter = threading.Thread(target=lighter)
lighter.start()
landrover = threading.Thread(target=car, args=("landrover", ))
tesla = threading.Thread(target=car, args=("tesla", ))
landrover.start()
tesla.start()