我正在尝试理解线程如何在python中工作,而我对一些事情略感困惑。
我的印象是你在使用线程时可以同时并行运行不同的任务?
下面的代码将演示我遇到的一些线程问题。 (我知道有更好的方法来编写端口扫描程序,但这将澄清我遇到的问题)
============开始示例============
import socket
import threading
def test2(start,end):
for i in range(int(start),int(end)):
server = 'localhost'
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
s.connect((server,i))
print("port", i , "is open", threading.current_thread().name)
s.close()
except socket.error as e:
s.close()
def threader():
print(threading.current_thread().name)
if threading.current_thread().name == "Thread-0":
test2(1,1000)
elif threading.current_thread().name == "Thread-1":
test2(1000,2000)
elif threading.current_thread().name == "Thread-2":
test2(2000,3000)
elif threading.current_thread().name == "Thread-3":
test2(3000,4000)
for i in range(4):
t = threading.Thread(target=threader, name= "Thread-"+str(i))
t.start()
============结束示例============
如果我用1个线程扫描1000个端口,通常需要大约7-8秒。
上面代码的问题在于执行时需要大约30秒。
如果所有线程并行运行并扫描相同数量的端口,是否需要大约7-8秒才能执行?
如果有人能解释我在这里做错了什么,我真的很感激。
TIA!
答案 0 :(得分:4)
要考虑的一件事是CPython的线程实现。由于所谓的全局解释器锁定--GIL(您可以在https://wiki.python.org/moin/GlobalInterpreterLock找到更多信息),Python中没有真正的并行性。
这意味着由于需要在这些线程与其串行运行时之间进行上下文切换,因此在任务上运行更多线程实际上可能会产生更差的性能结果。
如果你想要一个真正的加速,你可以使用不同的Python实现,支持并行处理(如Jython)或查看multiprocessing
模块。
我修改了你的代码,给出了各种实现的运行时间示例:
2.47829794884 # serial port scan
2.47367095947 # threaded port scan
0.693325996399 # port scan using multiprocessing
结果来自Fedora 20,4核心CPU笔记本电脑扫描40000端口(或每个线程/进程10000个端口。