多线程,就是指有多个线程同时执行,从而提高工作效率。
多线程执行时依次在cpu上轮流执行,通过上下文进行切换。
python多线程不适合cpu密集操作型的任务,适合io操作密集型的任务。
多线程及锁示例
在多线程中的程序中,最重要的就是共享资源的使用限制,如下例子描述了使用锁来限制打印资源的抢用。
import threading
import time
def run(n):
lock.acquire()
print("task start", n)
lock.release()
time.sleep(1)
lock.acquire()
print("task done", n)
lock.release()
if __name__ == "__main__":
start_time = time.time()
lock = threading.Lock()
task_objs = []
for i in range(50):
t = threading.Thread(target = run, args=("t-%s" %i,))
t.start()
task_objs.append(t)
for t in task_objs:
t.join()
print("all threads has been finished...")
print("cost:",time.time() - start_time)
多线程及锁示例2
下例描述了以类的形式定义多线程,并在线程中使用锁。
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):
printlock.acquire()
print("runnint task ",self.n )
printlock.release()
time.sleep(self.sleep_time)
printlock.acquire()
print("task done,",self.n )
printlock.release()
if __name__ == "__main__":
start_time = time.time()
printlock = threading.Lock()
task_objs = []
for i in range(50):
t = MyThread("t-%s" %i, 1)
t.start()
task_objs.append(t)
for t in task_objs:
t.join()
print("all threads has been finished...")
print("cost:",time.time() - start_time)
多线程中守护线程示例
守护线程相当于仆人线程,为主人而生,在主人死的时候自动死去。
import threading
import time
def run(n):
lock.acquire()
print("task start", n)
lock.release()
time.sleep(1)
lock.acquire()
print("task done", n)
lock.release()
if __name__ == "__main__":
start_time = time.time()
lock = threading.Lock()
task_objs = []
for i in range(50):
t = threading.Thread(target = run, args=("t-%s" %i,))
t.setDaemon(True)
t.start()
task_objs.append(t)
time.sleep(1)
lock.acquire()
print("all threads has finished...", threading.current_thread(), threading.active_count())
print("cost:",time.time() - start_time)
lock.release()
多线程中队列-生产者消费者示例
Queue是常见的多线程中使用的数据类型,该容器可以有先进先出、先进后出、指定优先级共三种。
import threading,time
import queue
q = queue.Queue(maxsize = 10)
def Producer(name):
count = 1
while True:
q.put("骨头%s" % count)
lock.acquire()
print("[%s]生产了骨头[%s]" %(name, count))
lock.release()
count += 1
time.sleep(0.5)
def Consumer(name):
while True:
lock.acquire()
print("[%s] 取到[%s] 并且吃了它..." %(name, q.get()))
lock.release()
time.sleep(1)
if __name__ == "__main__":
lock = threading.Lock()
p = threading.Thread(target=Producer,args=("张三",))
c1 = threading.Thread(target=Consumer,args=("李四",))
c2 = threading.Thread(target=Consumer,args=("王五",))
p.start()
c1.start()
c2.start()
多线程中Event示例
Event对象维护一个内部标志标,志初始值为False,通过set()可以将其置为True。
wait(timeout)则用于堵塞线程直至Flag被set,isSet()用于查询标志位是否为True,Clear()则用于清除标志位,使之为False。
import time
import threading
event = threading.Event()
lock = threading.Lock()
def lighter():
count = 0
event.set()
while True:
if count > 5 and count < 10:
event.clear()
lock.acquire()
print("\033[41;1mred light is on....\033[0m")
lock.release()
elif count >10:
event.set()
count = 0
else:
lock.acquire()
print("\033[42;1mgreen light is on....\033[0m")
lock.release()
time.sleep(1)
count +=1
def car(name):
while True:
if event.is_set():
lock.acquire()
print("[%s] running..."% name )
lock.release()
time.sleep(1)
else:
lock.acquire()
print("[%s] sees red light , waiting...." %name)
lock.release()
event.wait()
lock.acquire()
print("\033[34;1m[%s] green light is on, start going...\033[0m" %name)
lock.release()
light = threading.Thread(target = lighter,)
light.start()
car1 = threading.Thread(target = car,args = ("BMW",))
car1.start()
多线程中信号量示例
信号量可以用来限制运行线程的个数等。
import threading, time
def run(n):
semaphore.acquire()
time.sleep(1)
lock.acquire()
print("run the thread: %s\n" % n)
lock.release()
semaphore.release()
if __name__ == '__main__':
semaphore = threading.BoundedSemaphore(5)
lock = threading.Lock()
for i in range(22):
t = threading.Thread(target=run, args=(i,))
t.start()
while threading.active_count() != 1:
pass
else:
print('---all threads done---')