《Python核心编程》18.多线程编程(三)

18.6使用threading模块

#!/usr/bin/env python
# -*- coding:utf-8 -*-

"""从Thread类中派生出一个子例,创建一个这个子类的实例"""

import threading
from time import sleep, ctime

loops = (4, 2)


class MyThread(threading.Thread):
    """
    1.子类化Thread类
    2.要先调用基类的构造器,进行显式覆盖
    3.重新定义run()函数
    """
    def __init__(self, func, args, name=''):
        super(MyThread, self).__init__()
        self.name = name
        self.func = func
        self.args = args

    def run(self):
        self.func(*self.args)


def loop(nloop, nsec):
    print 'start loop', nloop, 'at:', ctime()
    sleep(nsec)
    print 'loop', nloop, 'done at:', ctime()


def main():
    print 'starting at:', ctime()
    threads = []
    nloops = range(len(loops))

    for i in nloops:
        t = MyThread(loop, (i, loops[i]), loop.__name__)  # 创建子类的实例
        threads.append(t)

    for i in nloops:
        threads[i].start()

    for i in nloops:
        threads[i].join()

    print 'all DONE at:', ctime()

if __name__ == '__main__':
    main()

18.7MyThread子类化

#!/usr/bin/env python
# -*- coding:utf-8 -*-

"""
1.单独化子类,让Thread的子类更加通用。
2.加上getResult()函数译返回函数的运行结果。

"""
import threading
from time import ctime


class MyThread(threading.Thread):
    def __init__(self, func, args, name=''):
        threading.Thread.__init__(self)
        self.name = name
        self.func = func
        self.args = args

    def getResult(self):
        return self.res

    def run(self):
        print 'starting', self.name, 'at:', ctime()
        self.res = apply(self.func, self.args)
        print self.name, 'finished at:', ctime()

18.8斐波那契、阶乘、累加和

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from myThread import MyThread
from time import ctime, sleep


def fib(x):
    """求斐波那契数列之和"""
    sleep(0.005)
    if x < 2:
        return 1
    return fib(x-2) + fib(x-1)


def fac(x):
    """求阶乘"""
    sleep(0.1)
    if x < 2:
        return 1
    return x * fac(x-1)


def sum_(x):
    """自然数累加和"""
    sleep(0.1)
    if x < 2:
        return 1
    return x + sum_(x-1)

funcs = [fib, fac, sum_]  # 将三个函数放到列表中
n = 12


def main():
    nfuncs = range(len(funcs))  # nfuncs = range(3)

    print '*** SINGLE THREAD'  # 单线程计算三个函数
    for i in nfuncs:
        print 'staring', funcs[i].__name__, 'at:', ctime()  # 打印出函数名称,开始运行时间
        print funcs[i](n)  # 打印计算结果
        print funcs[i].__name__, 'finished at:', ctime()  # 打印出函数名称,结束运行时间

    print '
*** MULTIPLE THREADS'  # 多线程计算三个函数
    threads = []
    for i in nfuncs:
        t = MyThread(funcs[i], (n,), funcs[i].__name__)  # 实例化三个MyThread对象
        threads.append(t)  # 将三个对象放到列表中

    for i in nfuncs:
        threads[i].start()  # 启动三个线程

    for i in nfuncs:
        threads[i].join()  # join()会等到线程结束或超时,即允许主线程等待线程结束
        print threads[i].getResult()  # 调用对象的getResult()方法

    print 'all DONE'

if __name__ == '__main__':  # 独立运行脚本,即在此脚本在直接运行时,才会调用main()函数
    main()

18.9生产者-消费者问题

#!/usr/bin/env python
# -*- coding: utf8 -*-

from random import randint  # randint随机进行生产和消耗
from time import sleep
from Queue import Queue
from myThread import MyThread


def writeQ(queue):
    print 'producing object for Q...', queue.put('xxx', 1)  # 把xxx对象放进队列中,并等待队列中有空间为止
    print "size now", queue.qsize()  # 返回队列大小


def readQ(queue):
    val = queue.get(1)  # 从队列中取出一个对象(消耗)
    print 'consumed object form Q... size now', queue.qsize()  # 返回队列大小


def writer(queue, loops):
    """一次往队列中放进一个对象,等待一会,然后再做给定次数的相同的事"""
    for i in range(loops):
        writeQ(queue)  # 调用writeQ,放进一个对象
        sleep(randint(1, 3))  # 随机睡眠1~3秒


def reader(queue, loops):
    """一次从队列中取出一个对象,等待一会,然后做给定次数的相同的事"""
    for i in range(loops):
        readQ(queue)
        sleep(randint(2, 5))  # 睡眠时间比 write 中的长,以使 reader 在取数据的时候能够拿到数据

funcs = [writer, reader]
nfuncs = range(len(funcs))


def main():
    nloops = randint(2, 5)
    q = Queue(32)  # 创建一个大小为32的对象,和 q 绑定

    threads = []
    for i in nfuncs:
        t = MyThread(funcs[i], (q, nloops), funcs[i].__name__)  # 实例化 writer, reader 这两个对象
        threads.append(t)  # 放入空列表中

    for i in nfuncs:
        threads[i].start()  # 启动线程

    for i in nfuncs:
        threads[i].join()  # join()会等到线程结束或超时,即允许主线程等待线程结束

    print 'all DONE'

if __name__ == '__main__':  # 独立运行脚本
    main()
原文地址:https://www.cnblogs.com/twtp/p/5485674.html