昨天纠结了一会儿线程池的问题,终于可以使这个线程池可用了,真切的感受到了多线程的执行速度确实很犀利,原来的单线程端口扫描那个速度实在不敢恭维,换
成多线程之后马上有了数量级的飞跃(当然看你定义线程数的大小,不能太大,否则线程的额外开销会严重影响性能,过犹不及),下面是代码部分:

from socket import *
from threading import Thread
from Queue import Queue
 
def scan(ip,port):
    s=socket(AF_INET,SOCK_STREAM)
    result=s.connect_ex((ip,port))
    if(result==0):
        print 'Port %d: OPEN' % port
    s.close()
 
class Worker(Thread):
    def __init__(self,taskQueue):
        Thread.__init__(self)
        self.setDaemon(True)
        self.taskQueue=taskQueue
        self.start()
 
    def run(self):
        while True:
            try:
                callable,args,kwds=self.taskQueue.get()
                callable(*args,**kwds)
            except:
                break
 
class ThreadPool:
    def __init__(self,ip):
        self.threads=[]
        self.taskQueue=Queue()
        self.threadNum=10
        self.__create_taskqueue(ip)
        self.__create_threadpool(self.threadNum)
 
    def __create_taskqueue(self,ip):
        for i in range(20,10000):
            self.add_task(scan,ip,i)
 
    def __create_threadpool(self,threadNum):
        for i in range(threadNum):
            thread=Worker(self.taskQueue)
            self.threads.append(thread)
 
    def add_task(self,callable,*args,**kwds):
        self.taskQueue.put((callable,args,kwds))
 
    def waitfor_complete(self):
        while len(self.threads):
            thread=self.threads.pop()
            thread.join(0.1)
            if thread.isAlive() and not self.taskQueue.empty():
                self.threads.append(thread)
        print 'scaning is over!'
 
if __name__=='__main__':
    target=raw_input('Enter host to scan:')
    targetIP=gethostbyname(target)
    print 'Starting scan on host',targetIP
    tp=ThreadPool(targetIP)
    tp.waitfor_complete()

在这里就直说小callable这个函数,它的功能是检查一个对象(python里面皆是对象)是否是可调用的,如果为真则返回True,如果为假则返回False。对于一个类来说,如果其含有__call__()方法,则也被认为是可调用的。

来源:http://www.oschina.net/question/220339_76762