使用实例

import threading
import time

lock = threading.Lock()
thread_list = []

class ThreadClass(threading.Thread):
    def __init__(self, threadName):
        threading.Thread.__init__(self)
        self.threadName = threadName

    def run(self):
        lock.acquire()
        for i in range(0, 10):
            print('{}'.format(self.threadName), ':', str(i))
            time.sleep(2)
        lock.release()

for i in range(3):
    thread = ThreadClass('thread {}'.format(i))
    thread_list.append(thread)
    thread.start()

for thread in thread_list:
    if thread:
        thread.join()

输出结果:

thread 0 : 0
...
thread 0 : 9
thread 1 : 0
...
thread 1 : 9
thread 2 : 0
...
thread 2 : 9

queue

queue 模块中提供了同步的、线程安全的队列类,这些队列都实现了锁原语,能够在多线程中直接使用,可以使用队列来实现线程间的同步。

import queue

q = queue.Queue(number) # 新建一个队列,默认情况下先进先出。number代表新建队列的大小,不写则默认为无限大

q.put(item, block=True, timeout=None) # 入栈,默认情况下Block为True,代表当队列已满时会造成阻塞,timeout表示阻塞时间,为None则一直阻塞
q.put_nowait(item) # 非阻塞的入栈,相当于 q.put(item, False)

q.get(block=True, timeout=None) # 出栈,默认情况下Block为True,代表当队列为空时会造成阻塞,timeout表示阻塞时间,为None则一直阻塞
q.get_nowait() # 非阻塞的出栈,相当于 q.get(False),它在向一个空队列取值的时候会抛一个Empty异常

q.empty() # 如果队列对空则返回True
q.full() # 如果队列满了则返回True

q.task_done() # 告诉queue这个队列item的任务已经完成了
q.join() # 在queue里的任务完成之前阻塞线程,直到队列里所有的任务都是task_done()

可以将queue看做是一个储存任务所需数据的队列,以此来控制线程的数目。当queue内储存的数量达到线程数量最大值时,再向queue中put则会造成阻塞,直到某线程完成任务q.get() + task_done()

import queue
from time import sleep
import random

q = queue.Queue(1) # 限制队列大小为1

for i in range(5):
    q.put(i)
print('all put in queue')
# 无输出,队列阻塞

for i in range(5):
    if q.full():
        item = q.get() # 这个举动会从queue队列里取出一个元素
        print('queue is full, get {}'.format(item))
        sleep(random.randrange(2, 5))
        q.task_done()
    q.put(i) # 当队列已满,而又没有item取出时会造成阻塞

print(q.full())
# 依次输出
# queue is full, get 0
# queue is full, get 1
# queue is full, get 2
# queue is full, get 3
# True

queue结合threading

import queue
from time import sleep
import random
import threading


class TestThread(threading.Thread):
    def __init__(self, que):
        threading.Thread.__init__(self)
        self.queue = que

    def run(self):
        while True: # 需要通过循环来不断的运行任务
            item = self.queue.get()
            sleep(random.randrange(2, 3))
            print('queue is full, get {}'.format(item))
            self.queue.task_done()

def start_thread():
    for thread in threads:
        thread.start()

q = queue.Queue(5)

# 开启5个线程
for i in range(5):
    t = TestThread(q)
    t.daemon = True
    t.start()

# 总共有20个数据跑在五个线程里
for i in range(20):
    q.put(i)

q.join()

results matching ""

    No results matching ""