使用Python进行线程编程


对于Python来说,并不缺少并发选项,其标准库包括了对线程、进程和异步I/O的支持。在许多情况下,通过创建诸如异步、线程和子进程之类的高层模块,Python简化了各种并发方法的使用。除了标准库之外,还有一些第三方的解决方案。例如Twisted、Stackless和进程Module。因为GIL,CPU受限的应用程序无法从线程中受益。使用Python时,建议使用进程,或者混合创建进程和线程。

首先弄清楚进程和线程的区别。线程和进程的不同之处在于,它们共享状态、内存和资源。对于线程来说,这个简单的区别既是它的优势,又是它的缺点。一方面,线程是轻量级的,并且相互之间易于通信,但另一方面,它们也带来了包括死锁、争用条件和好复杂性在内的各种问题。幸运的是,由于GIL和队列模块,与采用其他的语言相比,采用Python语言在线程实现的复杂性上要低的多。

《Python开发技术详解》.( 周伟,宗杰).[高清PDF扫描版+随书视频+代码]

Python脚本获取Linux系统信息

Python下使用MySQLdb模块

一个简单的demo:


#!/usr/bin/env python

import Queue

import threading

import urllib2

import time

 

hosts = ["http://www.baidu.com", "http://www.sina.com.cn", "http://www.letv.com"]

 

class ThreadUrl(threading.Thread):

    def __init__(self, queue):

        threading.Thread.__init__(self)

        self.queue = queue

       

    def run(self):

        while True:

            host = self.queue.get()

            url = urllib2.urlopen(host)

            print url.read(1024)

            self.queue.task_done()

           

def main():

    for i in range(5):

        t = ThreadUrl(queue)

        t.setDaemon(True)

        t.start()

   

    for host in hosts:

        queue.put(host)

   

    queue.join()

 

if __name__ == "__main__":

    start = time.time()

    main()

    print "Elapsed Time:%s" % (time.time() - start)

在Python中使用线程时,这个模型是一种很常见的并且推荐使用的方式。具体工作步骤描述如下:

1. 创建一个Queue.Queue()队列实例,然后向这个队列内灌数据。

2. 将灌进数据的实例传递给线程类,然后通过继承threading.Thread的方式创建。

3. 生成守护进程池(t.setDaemon(True))。

4. 每次从queue中pop一个项目,并使用该线程中的数据和run方法以执行相应的工作。

5. 在完成这项工作之后,使用queue.task_done()方法向任务完成的队列发送一个信号。

6. 对队列执行join操作,实际上意味着等到queue为空,再退出主程序。

在使用这个模式时需要注意一点:通过将守护线程设置为True,将允许主线程或者程序仅在守护线程处于活动状态时才能够退出。这种方式创建了一种简单的方式以控制程序流程,因为在退出之前,你可以对queue执行join操作或者等到队列为空。

说明:

join():保持阻塞状态,直到处理了队列中的所有项目为止。在将一个项目添加到该队列时,未完成的任务的总数就会增加。当使用者线程调用task_done()以表示检索了该项目、并完成了所有的工作时,那么未完成的任务的总数就会减少。当未完成的任务的总数减少到零时,join()就会结束阻塞状态。

更多详情见请继续阅读下一页的精彩内容:

  • 1
  • 2
  • 下一页

相关内容