Python, getting 'NoneType' object has no attribute 'something' - 退出多线程程序时出错
Python, getting 'NoneType' object has no attribute 'something' - error when exiting a multithreaded program
我有一个多线程程序,但在使用键盘中断时无法完全退出它时遇到了一些问题。有没有办法即使有多个线程我也可以干净地退出程序 运行ning?
这是从主线程关闭程序时给出错误的代码。
def oneround(self):
try:
threadLocal.s.send(threadLocal.message)
threadLocal.next_time += threadLocal.delay
threadLocal.sch.enterabs(threadLocal.next_time, 0, self.oneround, ())
if self.duration != 0 and time.time() > self.timeout:
print '\n' + 'Client socket closed after ' + str(self.duration) + ' seconds'
threadLocal.s.close()
os.kill(os.getpid(), signal.SIGINT)
except IOError as (errno, strerror):
if errno == 111:
print 'Connection failed'
threadLocal.s.close()
这是整个错误消息:
线程 Thread-1 中的异常(很可能在解释器关闭期间引发):
回溯(最近调用最后):
文件“/usr/lib/python2.7/threading.py”,第 810 行,在 __bootstrap_inner
中
文件“/usr/lib/python2.7/threading.py”,第 763 行,在 运行
中
文件 "trafgen6.py",第 592 行,在 init
中
文件“/usr/lib/python2.7/sched.py”,第 117 行,在 运行
中
文件 "trafgen6.py",第 598 行,单轮
类型'exceptions.AttributeError': 'NoneType'对象没有属性's'
编辑这是客户端的其余代码-class
class Client(QThread):
def __init__(self, host, port, rate, duration, parent = None):
super(Client, self).__init__(parent)
threadLocal.sch = sched.scheduler(time.time, time.sleep)
threadLocal.next_time = time.time()
threadLocal.sch.enterabs(threadLocal.next_time, 0, self.oneround, ())
host = host
port = port
speed = rate
self.duration = duration
threadLocal.delay = 1.0 / (speed*128)
n = bool(True)
openfile = open('1024')
threadLocal.message = openfile.read()
threadLocal.s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
threadLocal.s.setblocking(0)
try:
threadLocal.s.connect((host,port))
threadLocal.s.send(threadLocal.message)
time.sleep(0.1)
foo = threadLocal.s.recvfrom(1500)
if foo != " ":
pass
except IOError as (errno, strerror):
if errno == -9:
n = bool(False)
print 'Invalid address'
os.kill(os.getpid(), signal.SIGINT)
if errno == 11:
n = bool(False)
print 'Connection failed'
os.kill(os.getpid(), signal.SIGINT)
if n == True:
self.timeout = time.time() + duration
threadLocal.sch.run()
编辑 2 这是主线程的代码
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():
ip = ni.ifaddresses(i)[ni.AF_INET6][0]['addr']
if not ip.startswith('fe80') and not i.startswith('lo'):
list.insert(0,i)
parser = argparse.ArgumentParser(description='Send Ipv6 traffic through your network')
group1 = parser.add_mutually_exclusive_group()
group2 = parser.add_mutually_exclusive_group()
threadLocal = threading.local()
list = []
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='Specifies how long traffic will be sent| Default (0) is unlimited', default=0)
parser.add_argument('-r', '--rate',
action='store', dest='rate', type=int,
help='Sets the rate at which traffic will be sent | Default 1Mb/s', default=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 = threading.Thread(target=Server, args=[args.interface, args.port])
thread1.setDaemon(True)
thread1.start()
mode = 1
if args.client and args.targetip:
thread1 = threading.Thread(target=Client, args=[args.targetip, args.port, args.rate, args.time])
thread1.setDaemon(True)
thread1.start()
mode = 2
if threading.active_count() > 0:
calculator(mode)
这里是主线程的代码
class calculator(QThread):
def __init__(self, mode, parent = None):
super(calculator, self).__init__(parent)
mb = 1048576.00
try:
while True:
try:
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)
sys.stdout.write('\r' + 'Outbound traffic ' + str(out) + 'Mb/s ' + 'Inbound traffic ' + str$
sys.stdout.flush()
except KeyboardInterrupt:
if mode == 1:
print '\n' + 'Server stopped'
raise
elif mode == 2:
print '\n' + 'Client stopped'
raise
except KeyboardInterrupt:
sys.exit()
threading.local()
在调用时创建一个特定于当前 运行 线程的对象。您只需在主线程上执行一次,然后与所有其他线程共享。一旦解释器开始关闭并且超出范围,其他线程的引用就会损坏。
threadLocal = threading.local()
必须移动到您的实际线程中,即 Client.__init__
的顶部。
我有一个多线程程序,但在使用键盘中断时无法完全退出它时遇到了一些问题。有没有办法即使有多个线程我也可以干净地退出程序 运行ning?
这是从主线程关闭程序时给出错误的代码。
def oneround(self):
try:
threadLocal.s.send(threadLocal.message)
threadLocal.next_time += threadLocal.delay
threadLocal.sch.enterabs(threadLocal.next_time, 0, self.oneround, ())
if self.duration != 0 and time.time() > self.timeout:
print '\n' + 'Client socket closed after ' + str(self.duration) + ' seconds'
threadLocal.s.close()
os.kill(os.getpid(), signal.SIGINT)
except IOError as (errno, strerror):
if errno == 111:
print 'Connection failed'
threadLocal.s.close()
这是整个错误消息:
线程 Thread-1 中的异常(很可能在解释器关闭期间引发):
回溯(最近调用最后):
文件“/usr/lib/python2.7/threading.py”,第 810 行,在 __bootstrap_inner
中文件“/usr/lib/python2.7/threading.py”,第 763 行,在 运行
中文件 "trafgen6.py",第 592 行,在 init
中文件“/usr/lib/python2.7/sched.py”,第 117 行,在 运行
中文件 "trafgen6.py",第 598 行,单轮
类型'exceptions.AttributeError': 'NoneType'对象没有属性's'
编辑这是客户端的其余代码-class
class Client(QThread):
def __init__(self, host, port, rate, duration, parent = None):
super(Client, self).__init__(parent)
threadLocal.sch = sched.scheduler(time.time, time.sleep)
threadLocal.next_time = time.time()
threadLocal.sch.enterabs(threadLocal.next_time, 0, self.oneround, ())
host = host
port = port
speed = rate
self.duration = duration
threadLocal.delay = 1.0 / (speed*128)
n = bool(True)
openfile = open('1024')
threadLocal.message = openfile.read()
threadLocal.s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
threadLocal.s.setblocking(0)
try:
threadLocal.s.connect((host,port))
threadLocal.s.send(threadLocal.message)
time.sleep(0.1)
foo = threadLocal.s.recvfrom(1500)
if foo != " ":
pass
except IOError as (errno, strerror):
if errno == -9:
n = bool(False)
print 'Invalid address'
os.kill(os.getpid(), signal.SIGINT)
if errno == 11:
n = bool(False)
print 'Connection failed'
os.kill(os.getpid(), signal.SIGINT)
if n == True:
self.timeout = time.time() + duration
threadLocal.sch.run()
编辑 2 这是主线程的代码
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():
ip = ni.ifaddresses(i)[ni.AF_INET6][0]['addr']
if not ip.startswith('fe80') and not i.startswith('lo'):
list.insert(0,i)
parser = argparse.ArgumentParser(description='Send Ipv6 traffic through your network')
group1 = parser.add_mutually_exclusive_group()
group2 = parser.add_mutually_exclusive_group()
threadLocal = threading.local()
list = []
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='Specifies how long traffic will be sent| Default (0) is unlimited', default=0)
parser.add_argument('-r', '--rate',
action='store', dest='rate', type=int,
help='Sets the rate at which traffic will be sent | Default 1Mb/s', default=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 = threading.Thread(target=Server, args=[args.interface, args.port])
thread1.setDaemon(True)
thread1.start()
mode = 1
if args.client and args.targetip:
thread1 = threading.Thread(target=Client, args=[args.targetip, args.port, args.rate, args.time])
thread1.setDaemon(True)
thread1.start()
mode = 2
if threading.active_count() > 0:
calculator(mode)
这里是主线程的代码
class calculator(QThread):
def __init__(self, mode, parent = None):
super(calculator, self).__init__(parent)
mb = 1048576.00
try:
while True:
try:
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)
sys.stdout.write('\r' + 'Outbound traffic ' + str(out) + 'Mb/s ' + 'Inbound traffic ' + str$
sys.stdout.flush()
except KeyboardInterrupt:
if mode == 1:
print '\n' + 'Server stopped'
raise
elif mode == 2:
print '\n' + 'Client stopped'
raise
except KeyboardInterrupt:
sys.exit()
threading.local()
在调用时创建一个特定于当前 运行 线程的对象。您只需在主线程上执行一次,然后与所有其他线程共享。一旦解释器开始关闭并且超出范围,其他线程的引用就会损坏。
threadLocal = threading.local()
必须移动到您的实际线程中,即 Client.__init__
的顶部。