从子线程而不是正常退出获取AttributeError

时间:2015-04-15 16:50:57

标签: python multithreading debugging attributeerror

我有多线程程序,它有一个处理计算器和客户端或服务器线程的主线程。出于某种原因,当我尝试使用无效参数启动客户端(-d 1,应该类似于2001:dead:30 :: 5)而不是退出并打印帮助文本时,它会从计算器线程中给出属性错误

提前感谢您提供的任何帮助

这是错误消息

root@nyoa-VirtualBox:/home/nyoa# python trafgen6.py -c -d 1
Invalid address
closing client
Traceback (most recent call last):
  File "trafgen6.py", line 779, in <module>
    thread2.start()
  File "/usr/lib/python2.7/threading.py", line 750, in start
    self.__started.wait()
  File "/usr/lib/python2.7/threading.py", line 620, in wait
    self.__cond.wait(timeout)
  File "/usr/lib/python2.7/threading.py", line 339, in wait
    waiter.acquire()
KeyboardInterrupt
Exception AttributeError: "'calculator' object has no attribute    'stoprequest'" in <module 'threading' from '/usr/lib/python2.7   /threading.pyc'> ignored
Unhandled exception in thread started by 
sys.excepthook is missing
lost sys.stderr

这是我负责这部分的代码

class Client(threading.Thread):

        threadLocal = threading.local()

        def __init__(self, host, port, rate, duration, parent = None):
          super(Client, self).__init__(parent)
          self.host = host
          self.port = port
          self.rate = rate
          self.duration = duration

        def run(self):
          self.stoprequest = threading.Event()
          self.threadLocal.sch = sched.scheduler(time.time, time.sleep)
          self.threadLocal.next_time = time.time()
          self.threadLocal.sch.enterabs(self.threadLocal.next_time, 0, self.oneround, ())

          host = self.host
          port = self.port
          speed = self.rate
          duration = self.duration
          self.threadLocal.delay = 1.0 / (speed*128)
          n = bool(False)
          error = (False)
          openfile = open('1024')
          self.threadLocal.message = openfile.read()

          self.threadLocal.s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
          self.threadLocal.s.setblocking(0)
          try:
                self.threadLocal.s.connect((host,port))
                self.threadLocal.s.send(self.threadLocal.message)
                time.sleep(0.1)
                if len(self.threadLocal.s.recvfrom(1500)) > 1:
                        n = (True)
          except IOError as (errno, strerror):
                if errno == -9:
                        print 'Invalid address'
                        error = (True)
                        os.kill(os.getpid(), signal.SIGINT)
                if errno == 11:
                        print 'Connection failed'
                        error = (True)
                        os.kill(os.getpid(), signal.SIGINT)
                if errno == -2:
                        print 'Name or service unknown'
                        error = (True)
                        os.kill(os.getpid(), signal.SIGINT)

          if n == True:
                self.timeout = time.time() + duration
                self.threadLocal.sch.run()
          elif error == False:
                print 'Connection failed'
                os.kill(os.getpid(), signal.SIGINT)

        def oneround(self):
          if not self.stoprequest.isSet():
            try:
                self.threadLocal.s.send(self.threadLocal.message)
                self.threadLocal.next_time += self.threadLocal.delay
                if self.duration != 0 and time.time() > self.timeout:
                        print '\n' + 'Client socket closed after ' + str(self.duration) + ' seconds'
                        self.threadLocal.s.close()
                        os.kill(os.getpid(), signal.SIGINT)
                else:
                        self.threadLocal.sch.enterabs(self.threadLocal.next_time, 0, self.oneround, ())

            except IOError as (errno, strerror):
                if errno == 111:
                        print '\n' + 'Connection lost'
                        self.threadLocal.s.close()
                        os.kill(os.getpid(), signal.SIGINT)

        def join(self, timeout=None):
          self.stoprequest.set()
          super(Client, self).join(timeout)

class calculator(threading.Thread):

        def __init__(self, parent = None):
          super(calculator, self).__init__(parent)

        def run(self):
          self.stoprequest = threading.Event()
          mb = 1048576.00
          while not self.stoprequest.isSet():
                sent = {}
                recv = {}
                inwards = []
                out = []
                total = []
                n = 1
                for i in ni.interfaces():
                        counter = psutil.net_io_counters(pernic=True)[i]
                        sent.update({n:counter.bytes_sent})
                        recv.update({n:counter.bytes_recv})
                        n +=1
                time.sleep(1)
                n = 1
                for i in ni.interfaces():
                        counter = psutil.net_io_counters(pernic=True)[i]
                        totalsent = counter.bytes_sent - sent[n]
                        totalrecv = counter.bytes_recv - recv[n]
                        alldata = totalsent + totalrecv
                        self.totalout = (totalsent/mb) * 8
                        self.totalin = (totalrecv/mb) * 8
                        self.totalinout = (alldata/mb) * 8
                        inwards.insert((n-1), float("%.2f" % self.totalin))
                        out.insert((n-1), float("%.2f" % self.totalout))
                        total.insert((n-1), float("%.2f" % self.totalinout))
                        n += 1
                inwards = sum(inwards)
                out = sum(out)
                total = sum(total)
                if not self.stoprequest.isSet():
                        sys.stdout.write('\r' + 'Out ' + str(out) + 'Mb/s     ' + 'In ' + str(inwards) + 'Mb/s     '   'Total ' + str(total) + 'Mb/s   ')
                        sys.stdout.flush()

        def join(self, timeout=None):
          self.stoprequest.set()
          super(calculator, self).join(timeout)


if __name__ == '__main__':
        f = open('1024','w')
        for i in range(0, 962):
                f.write('@')
        f.close()


        def valid_interfaces():
                for i in ni.interfaces():
                        try:
                                ip = ni.ifaddresses(i)[ni.AF_INET6][0]['addr']
                                if not ip.startswith('fe80') and not i.startswith('lo'):
                                        list.insert(0,i)
                        except KeyError:
                                print 'Interface \"' + i + '\" does not have an IP address'

        parser = argparse.ArgumentParser(description='Send Ipv6 traffic through your network')
        group1 = parser.add_mutually_exclusive_group()
        group2 = parser.add_mutually_exclusive_group()
        mode = 0
        list = []
        threads = []
        ports = []
        valid_interfaces()

        group1.add_argument('-g', '--gui',
                        action='store_true', dest='gui',
                        help='Start graphical user interface. Do not use other arguments with this option')
        group1.add_argument('-s', '--server',
                        action='store_true', dest='server',
                        help='Set the program to run in server mode')
        group1.add_argument('-c', '--client',
                        action='store_true', dest='client',
                        help='Set the program to run in client mode')
        group2.add_argument('-i', '--interface',
                        action='store', dest='interface', choices=list,
                        help='Specifies the interface for server')
        group2.add_argument('-d', '--destip',
                        action='store', dest='targetip',
                        help='Sets the destination IPv6 address eg.2001:dead:beef::1')
        parser.add_argument('-p', '--port',
                        action='store', dest='port', type=int,
                        help='Specifies the port used by server or client | Default 5001', default=5001)
        parser.add_argument('-t', '--time',
                        action='store', dest='time', type=int,
                        help='Client only. Specifies in seconds how long traffic will be sent | Default (0) is unlimited', default=0)
        parser.add_argument('-r', '--rate',
                        action='store', dest='rate', type=int,
                        help='Client only. Sets the rate at which traffic will be sent (use plain numbers such as 1 or 1.5) | Default 1Mb/s', default=1)

        if len(sys.argv)==1:
                parser.print_help()
                sys.exit(1)

        args = parser.parse_args()

        if args.gui:
                app = QApplication(sys.argv)
                app.setStyle('cleanlooks')
                mainwindow = Application()
                mainwindow.show()
                sys.exit(app.exec_())

        if args.server and args.interface:
                thread1 = Server(host=args.interface, port=args.port)
                thread1.start()
                mode = 1

        if args.client and args.targetip:
                thread1 = Client(args.targetip, args.port, args.rate, args.time)
                thread1.start()
                mode = 2

        if mode != 0 and thread1.isAlive():
                thread2 = calculator()   
                thread2.start()

        if threading.active_count() > 1:
                while threading.active_count > 1:
                        try:
                                time.sleep(0.01)
                        except KeyboardInterrupt:
                                thread1.join()
                                if mode == 1:
                                        print '\n' + 'Server stopped'
                                elif mode == 2:
                                        print '\n' + 'Client stopped'
                                thread2.join()
                                sys.exit()
        else:
                parser.print_help()
                sys.exit(1)

0 个答案:

没有答案