python线程-请解释

python线程-请解释,python,multithreading,Python,Multithreading,我试图理解python中线程是如何工作的,但有几件事让我有些困惑 我的印象是,当使用线程时,您可以同时并行运行不同的任务 下面的代码将演示我在线程方面遇到的一些问题。 (我知道有更好的方法编写端口扫描仪,但这将澄清我遇到的问题) =============开始示例============ import socket import threading def test2(start,end): for i in range(int(start),int

我试图理解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()
================结束示例============

    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()
如果我用一个线程扫描1000个端口,通常需要7-8秒

上面代码的问题是,执行此操作大约需要30秒

如果所有线程都并行运行并且扫描相同数量的端口,那么执行是否应该花费大约7-8秒

如果有人能解释一下我做错了什么,我将不胜感激


蒂亚

> Pcthon的一个要考虑的是CPython线程的实现。由于所谓的全局解释器Lock-GIL(您可以在中找到更多信息),Python中没有真正的并行性

这意味着在一个任务上运行更多线程实际上可能会有更差的性能结果,因为需要在这些线程和它们的串行运行时之间进行上下文切换

如果您想要真正的加速,您可以使用支持并行处理的不同Python实现(如Jython)或查看
多处理
模块

我修改了您的代码,以给出各种实现的运行时间示例:

2.47829794884 # serial port scan
2.47367095947 # threaded port scan
0.693325996399 # port scan using multiprocessing

结果来自Fedora20,4核CPU笔记本电脑扫描40000个端口(或每个线程/进程10000个端口。

并发性和并行性之间存在差异。使用CPython和多线程,只能保证前者,不能保证后者。其他Python实现可能会给您更多自由。或者您可以使用多处理。我无法重现您看到的性能差异。线程对我来说,e实际上更快,这是有道理的,因为你在每个线程中进行I/O,这意味着GIL被释放。线程化和非线程化的代码运行所需的时间也不到一秒钟。你在哪个平台上?这个例子真的代表了你在真实程序中所做的事情吗?这对于threa来说是不寻常的ded性能要比非线程性能差得多,特别是当OP主要在线程中执行I/O时。这里似乎有比GIL更重要的事情。区别并不是很大-1000个端口的7-8秒将产生4000个端口的28-32秒。由于t它只是打开和关闭插座。