【问题标题】:How can I achieve multi-threading in Python? [socket programming]如何在 Python 中实现多线程? 【套接字编程】
【发布时间】:2017-09-22 15:49:19
【问题描述】:

我正在尝试在客户端中创建一个单独的线程,它以非阻塞方式从服务器套接字恢复消息。由于我的原始代码太长而且解释起来有点麻烦,所以我创建了一个示例程序,专注于我想做的事情。我尝试创建两个单独的线程,比如Thread t1Thread t2Thread t1 轮询套接字以检查任何接收到的数据,而 Thread t2 执行分配给它的任何任务。我期望它做的是,Thread t1 总是轮询,如果收到数据,它会在屏幕上打印它,Thread t2 会并行执行它正在做的任何事情。但是,由于某种原因,我无法让它工作。

我的示例程序是:

import threading
import time
import threading
from time import sleep
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 5555))
s.setblocking(0)
s.sendall(str.encode('Initial Hello'))

def this_thing():
    while True:
        try:
           data = s.recv(4096)
            print(data.decode('utf-8'))
        except:
            pass / break #not sure which one to use. Neither of it works

def that_thing():
    for i in range(10000):
        sleep(3)
        s.sendall(str.encode('Hello')
        print('happening2')

threading.Thread(target=this_thing(), args=[]).start()
threading.Thread(target=that_thing(), args=[]).start()

注意: 服务器套接字是一个简单的服务器,如果它接收到消息,它会向所有连接的套接字发送消息。 当我在Thread t1 中通过在异常中中断 运行程序时,只有我的Thread t2 继续运行。 Thread t1 没有收到服务器发送的任何数据

【问题讨论】:

  • 你永远不应该传入一个 except 块,捕获异常并记录它或只是打印它。要捕获您可以执行的任何异常,请尝试:code() except Exception as e: print(e)。不过,异常越具体越好。
  • @chatton :例外是:[WinError 10035] A non-blocking socket operation could not be completed immediately 这是有道理的,但是如果我将套接字更改为阻塞,它永远不会真正退出Thread t1,直到我收到一条不是我想要的消息去做。有什么办法吗?
  • threading.Thread(target=this_thing(), args=[]).start(),我很确定目标应该是函数本身,而不是函数的结果称呼。 target=this_thing() -> target=this_thing 我认为现在发生的事情是在创建第一个线程期间它陷入了无限循环。
  • 来自文档“target 是由 run() 方法调用的可调用对象”docs.python.org/2/library/threading.html 在这种情况下,this_thing 和 that_thing 是可调用对象。
  • 您应该能够简单地将 target=this_thing() 更改为 target=this_thing,that_thing 也一样

标签: python multithreading python-3.x sockets


【解决方案1】:

发生这种情况的原因是因为“目标”参数采用可调用对象。

来自文档 docs.python.org/2/library/threading.html

"target是run()方法调用的可调用对象"

在你的版本中

threading.Thread(target=this_thing(), args=[]).start()
threading.Thread(target=that_thing(), args=[]).start()

当您说 target=this_thing() 时,它会尝试评估对 this_thing 的调用的值,在您的情况下,它将进入一个 while True 循环,然后如果它要完成,它将评估为 None。

你想要做的是将这两行替换为

threading.Thread(target=this_thing, args=[]).start()
threading.Thread(target=that_thing, args=[]).start()

请注意,您现在正在传递函数本身。函数是一个可调用的对象。

【讨论】:

    【解决方案2】:

    python 3+ 的正确解决方案不是多线程,而是异步。

    查看 David Beazley 就此事发表的精彩演讲(49 分钟): https://www.youtube.com/watch?v=ZzfHjytDceU

    异步/套接字示例:https://gist.github.com/gregvish/7665915

    【讨论】:

      猜你喜欢
      • 2020-10-25
      • 2015-01-28
      • 2012-12-08
      • 1970-01-01
      • 2013-05-03
      • 1970-01-01
      • 1970-01-01
      • 2021-09-26
      • 1970-01-01
      相关资源
      最近更新 更多