1. 多线程、多进程、多协程。多进程简单举例举例:
# encoding:utf-8
import threading
import time
def thread_one():
time.sleep(3)
# threading.current_thread() 显示当前进程
print "我是线程一:我的作用是打印。%s" % threading.current_thread()
def thread_two():
time.sleep(3)
print "我是线程二:我想运行得更快一些。%s" % threading.current_thread()
def main():
# threading.enumerate()查看当前进程数量
print threading.enumerate()
first = threading.Thread(target=thread_one)
second = threading.Thread(target=thread_two)
first.start()
second.start()
print threading.enumerate()
if __name__ == '__main__':
main()
2. 继承自threading.thread类
这种方法分装性好,使用较多。
# encoding:utf-8
import threading
import time
class CodingThread(threading.Thread):
def run(self):
for x in range(3):
print "%s正在运行中.........." % threading.current_thread()
time.sleep(1)
class DrawingThread(threading.Thread):
def run(self):
for x in range(3):
print "%s画图正在进行中" % threading.current_thread()
time.sleep(1)
def main():
t1 = CodingThread()
t2 = DrawingThread()
t1.start()
t2.start()
if __name__ == '__main__':
main()
3. 多线程共享全局变量以及锁机制
3.1 不加锁情况下,示例代码如下:
# encoding:utf-8
import threading
VALUE = 0
class DrawingThread(threading.Thread):
def run(self):
global VALUE
for x in range(10000):
VALUE += 1
print VALUE
print threading.current_thread()
def main():
for x in range(2):
threader = DrawingThread()
threader.start()
if __name__ == '__main__':
main()
结果如下:
D:\Python3\python27\python.exe D:/PyCharm/dytt_spider/thread_spider.py
11341
<DrawingThread(Thread-1, started 10488)>
15961
<DrawingThread(Thread-2, started 7780)>
Process finished with exit code 0
3.2 加锁情况下,示例代码如下:
# encoding:utf-8
import threading
VALUE = 0
glock = threading.Lock()
class DrawingThread(threading.Thread):
def run(self):
global VALUE
# 上锁语法:glock.acquire()
glock.acquire()
for x in range(10000):
VALUE += 1
# 开锁语法:glock.release()
glock.release()
print VALUE
print threading.current_thread()
def main():
for x in range(2):
threader = DrawingThread()
threader.start()
if __name__ == '__main__':
main()
结果为:
D:\Python3\python27\python.exe D:/PyCharm/dytt_spider/thread_spider.py
10000
<DrawingThread(Thread-1, started 7856)>
20000
<DrawingThread(Thread-2, started 11864)>
Process finished with exit code 0
4. Lock版生产者和消费者模式
生产者模式和消费者模式,是多线程中常见的模式。全局变量需要使用一把锁。实例代码如下:
# encoding:utf-8
import threading
import random
import time
gMoney = 2000
gLock = threading.Lock()
gTotalTimes = 10
gTimes = 0
class Producer(threading.Thread):
def run(self):
global gMoney
global gTimes
while True:
money = random.randint(100, 1000)
gLock.acquire()
if gTimes >= gTotalTimes:
gLock.release()
break
gMoney += money
gTimes += 1
print "%s生产了%d元,剩余%d元。"%(threading.current_thread(), money, gMoney)
gLock.release()
time.sleep(2)
class Consumer(threading.Thread):
def run(self):
global gMoney
while True:
money = random.randint(100, 1000)
gLock.acquire()
if gTimes >= gTotalTimes:
gLock.release()
break
if money < gMoney:
gMoney -= money
print "%s消费了%d元,剩余%d元。" % (threading.current_thread(), money, gMoney)
else:
print "余额不足,剩余%d元" % (gMoney)
gLock.release()
time.sleep(2)
def main():
for x in range(3):
t = Producer()
t.start()
for x in range(3):
t = Consumer()
t.start()
if __name__ == '__main__':
main()
5. Condition版生产者和消费者模式
threading.Condition是继承自threading.Lock.
condition条件对象提供如下方法:
(1)threading.Condition()
(2)acquire(*args) 获取锁
(3)release()释放锁
(4)wait([timeout]) 等待
(5)notify(n=1) / notifyAll() 唤醒
示例代码如下:
# encoding:utf-8
import threading
import random
import time
gMoney = 1000
gLock = threading.Condition()
gTotalTimes = 10
gTimes = 0
class Producer(threading.Thread):
def run(self):
global gMoney
global gTimes
while True:
money = random.randint(100, 1000)
gLock.acquire()
if gTimes >= gTotalTimes:
gLock.release()
break
gMoney += money
gTimes += 1
print "%s生产了%d元,剩余%d元。"%(threading.current_thread(), money, gMoney)
gLock.notify_all()
gLock.release()
time.sleep(2)
class Consumer(threading.Thread):
def run(self):
global gMoney
while True:
money = random.randint(100, 1000)
gLock.acquire()
while money > gMoney:
if gTimes >= gTotalTimes:
gLock.release()
return
print "%s消费余额不足,剩余%d元。" % (threading.current_thread(), gMoney)
gLock.wait()
gMoney -= money
print "%s消费了%d元,剩余%d元。" % (threading.current_thread(), money, gMoney)
gLock.release()
time.sleep(2)
def main():
for x in range(3):
t = Producer()
t.start()
for x in range(3):
t = Consumer()
t.start()
if __name__ == '__main__':
main()
6.Queue线程安全队列
6.1 在线程中,访问一些全局变量,加锁是个常用的过程。Python的Queue模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列PriorityQueue。这些队列都实现了锁原语,能够在多线程中直接使用。可以使用队列来实现线程间的同步。队列:先进先出。栈:先进后出。相关的函数如下:
(1)初始化Queue(maxsize):创建一个先进先出的队列。
(2)qsize():返回队列的大小。
(3)empty():判断队列是否为空。
(4)full():判断队列是否满了。
(5)get():从队列中取最后一个数据。
(6)put():将一个数据放到队列中。
6.2 实例如下:
# encoding:utf-8
import Queue
q = Queue.Queue(4)
for x in range(3):
q.put(x+1)
for x in range(3):
print q.get()
# block默认值是True,如果队列中没有值,会一直阻塞在这里。
q.get(block=True)
# block默认值是True,如果队列中已经满了,会一直阻塞在这里,直到不满为止。
q.put(block=True)
print q.empty()
print q.full()
6.3 多线程和Queue安全线程的结合,示例如下:
# encoding:utf-8
import Queue
import time
import threading
q = Queue.Queue(4)
def set_value(q):
index = 1
while True:
q.put(index)
index += 1
time.sleep(3)
def get_value(q):
while True:
print q.get()
def main():
t1 = threading.Thread(target=set_value, args=[q])
t2 = threading.Thread(target=get_value, args=[q])
t1.start()
t2.start()
if __name__ == '__main__':
main()
6.4 使用生产者和消费者模式多线程下载offshore网站下的图片以及文章: