python多线程编程

本文详细介绍了Python中多线程的应用,包括多线程的基本使用方法、多线程中的锁机制、条件变量以及队列的应用,并通过具体示例展示了如何在多线程环境下进行资源共享和同步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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网站下的图片以及文章:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值