Python: 线程之间通信(源码拷贝即用)

目录

一、线程之间的几种通信方式

二、Lock()

三、Condition()

四、Event()

五、Queue

一、线程之间的几种通信方式
threading.Lock()/threading.RLock() - 互斥锁,在某一时刻只能有一个使用者访问该资源
threading.Condition() - 资源锁,可以提供挂起/唤醒等功能
threading.Event() - 事件,也可以提供类似资源锁的挂起/唤醒功能
Queue - 队列
二、Lock()
import threading

class MyThread(threading.Thread):
def __init__(self, mutex, arg):
threading.Thread.__init__(self, daemon=True)
self.mutex = mutex
self.arg = arg

def run(self):
for i in range(10000):
self.mutex.acquire()
self.arg['count'] = self.arg.get('count', 0) + 1
self.mutex.release()

self.mutex.acquire()
self.arg['done'] = self.arg.get('done', 0) + 1
self.mutex.release()


def main():
mutex = threading.Lock()
arg = dict()
n = 100
for i in range(n):
t = MyThread(mutex, arg)
t.start()

import time
while True:
print("count = [{0}], done = [{1}]".format(arg.get('count', -1), arg.get('done', -1)))
if arg.get('done', 0) == n:
break
time.sleep(1)

if "__main__" == __name__:
main()
三、Condition()
import time
import random
import threading

class NotiyThread(threading.Thread):
def __init__(self, name, cond):
threading.Thread.__init__(self)
self.cond = cond
self.name = name

def run(self):
# 等待 wait 线程的 wait() 操作,notify() 操作必须能满足所有的 wait() 操作,否则 wait 线程会卡住一直等待
time.sleep(random.randint(10, 11))
for i in range(3 * 5): # notify 3 * 15 次,因为5个 wait 线程,每个 wait 3 次
print("thread-{0} - {1} - send notify".format(self.name, i))
self.cond.acquire()
self.cond.notify()
self.cond.release()
print("thread-{0} - {1} - send notify ok".format(self.name, i))
time.sleep(random.randint(1, 2))
print("thread-{0} over".format(self.name))


class WaitThread(threading.Thread):
def __init__(self, name, cond):
threading.Thread.__init__(self)
self.cond = cond
self.name = name

def run(self):
time.sleep(random.randint(1, 3))
for i in range(3): # wait 3 次
print("thread-{0} - {1} - wait for notify ...".format(self.name, i))
self.cond.acquire()
self.cond.wait()
self.cond.release()
print("thread-{0} - {1} - get notify !".format(self.name, i))
print("thread-{0} over".format(self.name))


def main():
tlist = list()
n = 5
cond = threading.Condition()
t = NotiyThread('notify', cond)
tlist.append(t)
for i in range(n):
t = WaitThread('wait-' + str(i), cond)
tlist.append(t)

for t in tlist:
t.start()

for t in tlist:
print("waitting for {0} end".format(t.name))
t.join() # 等待线程结束


if "__main__" == __name__:
main()
四、Event()
from queue import Queue, Empty
import threading
import time
import random

class Task(object):
def __init__(self, event, option=''):
self.event = event
self.option = option
self.data = None


class ReadFileThread(threading.Thread):
def __init__(self, q):
threading.Thread.__init__(self)
self.q = q

def run(self):
for i in range(5):
time.sleep(random.randint(1, 3))
task = None
try:
task = self.q.get(timeout=10)
if 'readfile' == task.option:
task.data = 'file content:' + str(random.randint(100, 200))
task.event.set()
except Empty as e:
print("queue is empty before timeout:", str(e))


class PrintThread(threading.Thread):
def __init__(self, q):
threading.Thread.__init__(self)
self.q = q

def run(self):
for i in range(5):
task = Task(threading.Event(), option='readfile')
self.q.put(task)
task.event.wait()
print("get file data: [{0}]".format(task.data))


def main():
q = Queue()
reader = ReadFileThread(q)
printer = PrintThread(q)

reader.start()
printer.start()

printer.join()
reader.join()
print("exit")


if "__main__" == __name__:
main()
五、Queue
一个线程向 queue put 资源,另一个线程 get 资源。

from queue import Queue, Empty
import threading
import time, random


class Writer(threading.Thread):
def __init__(self, q):
threading.Thread.__init__(self, daemon=True)
self.q = q
self.done = False

def run(self):
for i in range(10):
p = 'product-' + str(i)
print("make product : [{0}]".format(p))
self.q.put(p)
time.sleep(random.randint(1, 3))
self.done = True


class Reader(threading.Thread):
def __init__(self, q):
threading.Thread.__init__(self, daemon=True)
self.q = q
self.done = False

def run(self):
while True:
try:
d = self.q.get(timeout=5)
print('get product :', d)
except Empty as e:
print("no product get")
break
self.done = True


def main():
q = Queue()
maker = Writer(q)
reader = Reader(q)

maker.start()
reader.start()

while True:
time.sleep(1)
if maker.done == True and reader.done == True:
print("maker and reader is done, quit")
break


if "__main__" == __name__:
main()

————————————————
版权声明:本文为CSDN博主「miaow~miaow」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/fengbohello/article/details/121522001

posted @ 2022-06-17 16:46  苍月代表我  阅读(1244)  评论(0)    收藏  举报