免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5321 | 回复: 3
打印 上一主题 下一主题

多线程不能退出 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-30 09:07 |只看该作者 |倒序浏览
想通过多线程的方式由一个脚本调用另外一个脚本,为此写了个简单的测试程序,程序就是由一段程序生成queue,然后调用一个叫做scanner.py的程序,scanner.py很简单,就是检测目标主机的TCP 22端口是否开放
但程序总是执行到最后一个线程完成后无法自动退出,请帮忙看看
P.S. 重点在于线程不能退出,因为该程序只是用于测试,所以不考虑功能的实现

调用程序代码

  1. #!/usr/bin/env python
  2. # coding=utf-8
  3. import os
  4. import sys
  5. import Queue
  6. import socket
  7. import threading

  8. class makeScanList(threading.Thread):
  9.     def __init__(self , ip , queue):
  10.         threading.Thread.__init__(self)
  11.         self.ip = ip
  12.         self.target = queue
  13.     def run(self):
  14.         self.target.put(self.ip)
  15. #
  16. class doScan(threading.Thread):
  17.     def __init__(self , queue):
  18.         threading.Thread.__init__(self)
  19.         self.target = queue
  20.     def run(self):
  21.         ip = self.target.get()
  22.         import subprocess
  23.         subprocess.Popen(['python','scanner.py',ip])
  24. #
  25. if __name__ == "__main__":
  26.     target = []
  27.     q = Queue.Queue()
  28.     for i in xrange(0,254):
  29.         target.append("192.168.10.%s" %str(i+1))
  30.     print "Start Scaning ..."
  31.     for i in target:
  32.         m = makeScanList( i , q )
  33.         m.start()
  34.     for i in target:
  35.         d = doScan(q)
  36.         d.start()
  37.     m.join()
  38.     d.join()
  39.     print "Scaning Complete !"
复制代码


scanner.py

  1. #!/usr/bin/env python
  2. import sys
  3. import socket
  4. ip = sys.argv[1]
  5. s = socket.socket()
  6. s.settimeout(1)
  7. try:
  8.     s.connect((ip,22))
  9.     print "IP : %s , SSH is Opened" %ip
  10. except:
  11.     print "IP : %s , SSH is Closed" %ip
复制代码

论坛徽章:
0
2 [报告]
发表于 2009-04-30 16:08 |只看该作者
改了一下你的程序:

#!/usr/bin/env python
# coding=utf-8
import os
import sys
import Queue
import socket
import threading
import time

class doScan(threading.Thread):
    def __init__(self , queue):
        threading.Thread.__init__(self)
        self.target = queue
    def run(self):
        ip = self.target.get()
        scan(ip)
def scan(ip):
    s = socket.socket()
    s.settimeout(1)
    try:
        s.connect((ip,22))
        print "\n IP : %s , SSH is Opened" %ip
    except:
        print "\n IP : %s , SSH is Closed" %ip
if __name__ == "__main__":
    q = Queue.Queue()
    for i in xrange(0,254):
        q.put("192.168.10.%s" %str(i+1))
    print "Start Scaning ..."
    qlist = []
    for i in xrange(q.qsize()):
        d = doScan(q)
        qlist.append(d)
        d.start()
    while len(qlist):
        thread = qlist.pop()
        thread.join()
    print "Scaning Complete !"


关于你说不能退出的问题:程序应该能正常退出的。 我这边是windows xp 环境,python 2.6 不知道你那边是什么情况。

建议:
1.添加Ip列表的时候我认为不该使用线程。
2.进行扫描的是还不该使用subprocess。
3.把扫描的模块放替换使用模块或者方法的方式。
4.创建线程也是极其消耗资源的。

希望能对你有所帮助。

论坛徽章:
0
3 [报告]
发表于 2009-04-30 16:34 |只看该作者
使用线程池写了一个:

scan.py

#!/usr/bin/env python
# coding=utf-8
import os
import sys
import Queue
import socket
import threading
import time
from ThreadPool import ThreadPool


def scan(ip):
    s = socket.socket()
    s.settimeout(1)
    try:
        s.connect((ip,22))
        print "\n IP : %s , SSH is Opened" %ip
    except:
        print " \n IP : %s , SSH is Closed" %ip
if __name__ == "__main__":

    print "Start Scaning ..."
    tp = ThreadPool(10)
    for i in xrange(0,254):
        tp.add_job( scan, "192.168.10.%s" %str(i+1))
    tp.wait_for_complete()
    print "Scaning Complete !"

ThreadPool.py

#!/usr/bin/env python
#coding:utf-8
#email:biansutao 【at】 gmail 【dot】com
import Queue
import threading
import sys
import time
import urllib

#替我们工作的线程池中的线程
class MyThread(threading.Thread):
        def __init__(self, workQueue, resultQueue,timeout=3, **kwargs):
                threading.Thread.__init__(self, kwargs=kwargs)
                #线程在结束前等待任务队列多长时间
                self.timeout = timeout
                self.setDaemon(True)
                self.workQueue = workQueue
                self.resultQueue = resultQueue
                self.start()

        def run(self):
                while True:
                        try:
                                #从工作队列中获取一个任务
                                callable, args = self.workQueue.get(timeout=self.timeout)
                                #我们要执行的任务
                                callable(args)                       
                        except Queue.Empty: #任务队列空的时候结束此线程
                                break
                        except :
                                print sys.exc_info()
                                raise
                               
class ThreadPool:
        def __init__( self, num_of_threads=10):
                self.workQueue = Queue.Queue()
                self.resultQueue = Queue.Queue()
                self.threads = []
                self.__createThreadPool( num_of_threads )

        def __createThreadPool( self, num_of_threads ):
                for i in range( num_of_threads ):
                        thread = MyThread( self.workQueue, self.resultQueue )
                        self.threads.append(thread)

        def wait_for_complete(self):
                #等待所有线程完成。
                while len(self.threads):
                        thread = self.threads.pop()
                        #等待线程结束
                        if thread.isAlive():#判断线程是否还存活来决定是否调用join
                                thread.join()
                               
        def add_job( self, callable, *args):
                self.workQueue.put( (callable,args) )

[ 本帖最后由 biansutao 于 2009-4-30 16:35 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2009-04-30 17:36 |只看该作者
原帖由 biansutao 于 2009-4-30 16:08 发表
建议:
1.添加Ip列表的时候我认为不该使用线程。
2.进行扫描的是还不该使用subprocess。


创建列表的线程是用之前程序改的,没太在意,估计对资源消耗有影响

subprocess主要是用来模拟import一个模块后执行的效果,因为实际环境中很可能也要import一下然后调用其他功能模块,我也在考虑能否用其他方式代替

我的环境是windows 2003 + python 2.5

朋友修改的程序我晚上测下看看行不行,不管怎么样,非常感谢你的帮助
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP