• 介绍

在Python的开发过程中,有时候会用到多线程的技术,例如在开发服务端程序时就不可避免的要使用多线程。

thread是相对低级的线程模块,threading是经过封装的功能比较强。

  • 最简单的一个多线程例子

[codesyntax lang="python"]


__author__ = 'suren'

import thread
import time

def task():
print(1)
pass

thread.start_new_thread(task, ())
thread.start_new_thread(task, ())

time.sleep(3)


[/codesyntax]

线程模块thread中启动线程的函数,需要至少两个参数:函数名、函数的参数列表。

  • 继承线程类

[codesyntax lang="python"]


__author__ = 'suren'

import threading
import time

class Task(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
pass

def run(self):
print('task thread started.')
pass

thread1 = Task()
thread2 = Task()

thread1.start()
thread2.start()

time.sleep(3)


[/codesyntax]

threading.Thread类中包含的函数有:

run(),线程启动时调用的代码

getName(),获取线程对象名称

setName(),设置线程对象名称

start(),启动线程的函数

join([timeout]),等待另一个线程运行结束后在调用

setDaemon(bool),设置子线程是否随着主线程一起结束,必须在start之前调用

isDaemon(),检查是否为守护线程

isAlive(),检查线程是否还在运行中

  • 简单线程锁

[codesyntax lang="python"]


__author__ = 'suren'

import thread
import time

suren_lock = thread.allocate_lock()
num = 0

def task():
global num
while True:
try:
suren_lock.acquire()

num += 1
time.sleep(0.1)

print('task running : %d' % (num))
finally:
suren_lock.release()
pass

thread.start_new_thread(task, ())
thread.start_new_thread(task, ())
thread.start_new_thread(task, ())
thread.start_new_thread(task, ())
thread.start_new_thread(task, ())

time.sleep(1)


[/codesyntax]

上面的代码中,如果把获取、释放锁的行注释掉再运行的话,你会发现每次打印出的内容都是不一样的。

  • 高级线程锁

[codesyntax lang="python"]


__author__ = 'suren'

import threading
import time

suren_lock = threading.RLock()
num = 0

class Task(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
pass

def run(self):
global num

while True:
try:
suren_lock.acquire()

num += 1
time.sleep(0.1)

print('task running : %d' % (num))
pass
finally:
suren_lock.release()
pass
pass

thread1 = Task()
thread2 = Task()
thread3 = Task()
thread4 = Task()
thread5 = Task()

thread1.start()
thread2.start()
thread3.start()
thread4.start()
thread5.start()

time.sleep(1)


[/codesyntax]

同样地,要是把上面代码中获取、释放锁的行注释掉的话,打印出来的内容是乱的。

  • 条件同步

[codesyntax lang="python"]


__author__ = 'suren'

import threading
import time

condition = threading.Condition()
num = 0

class Producer(threading.Thread):
def __init__(self):
global num

while True:
try:
if num > 0:
condition.wait()
else:
time.sleep(0.1)

pass
finally:
condition.release()
pass
pass

class Consumer(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
pass

def run(self):
global num

while True:
try:
condition.acquire()

if num <= 0:
condition.wait()
else:
print('num : %d' % (num))
num -= 1
condition.notify()
time.sleep(0.3)

pass
finally:
condition.release()
pass
pass

producer1 = Producer()
consumer1 = Consumer()
consumer2 = Consumer()
consumer3 = Consumer()
consumer4 = Consumer()

producer1.start()
consumer1.start()
consumer2.start()
consumer3.start()
consumer4.start()

time.sleep(1)


[/codesyntax]

  • 同步队列

[codesyntax lang="python"]


__author__ = 'suren'

import threading
import time
from Queue import Queue

class Producer(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.data = queue
pass

def run(self):
while True:
self.data.put(1)
time.sleep(0.1)
pass

class Consumer(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.data = queue
pass

def run(self):
while True:
self.data.get()
print(self.data.qsize())
pass

queue = Queue()
producer1 = Producer(queue)
producer2 = Producer(queue)
producer3 = Producer(queue)
producer4 = Producer(queue)
consumer = Consumer(queue)

producer1.start()
producer2.start()
producer3.start()
producer4.start()
consumer.start()

time.sleep(1)


[/codesyntax]

  • 参考

​javascript:void(0)​

​www.python.org/doc/2.5.2/lib/module-threading.html​​​