Cygwin中Python线程和Socket IO死锁问题

1 投票
1 回答
923 浏览
提问于 2025-04-16 01:37

我在Cygwin上用Python遇到了一个奇怪的并发问题。我正在运行两个线程:

  • 一个线程定期发送UDP数据包
  • 一个主线程等待键盘中断,当收到中断时,它通过一个布尔标志告诉UDP线程停止发送

在Linux(python 2.6)和Windows(Python 2.7)下,这个方法都能正常工作,但在Cygwin的Python(2.6)上却出现了问题。

在Cygwin中,发送数据包的线程会一直等到主线程从用户那里获取到输入(raw_input)后,才会发送UDP数据包。这种情况每次都会发生。以下是代码:

import sys
import socket
import threading
from time import sleep

class UdpPacketSender(threading.Thread):
    def __init__(self, address, port):
        threading.Thread.__init__ (self)
        self.address = (address, int(port))
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.send = True

    def run(self):
        while self.send:
            print "Sending packet..."
            self.socket.sendto("Hello", self.address)
            print "sent packet"
            sleep(1)
        self.socket.close()

    def stop_sending(self):
        self.send = False

sender = UdpPacketSender("127.0.0.1", 7000)
sender.start()
try:
    while True:
        raw_input()
except KeyboardInterrupt:
    print "Got keyboard interrupt, stopping"
    sender.stop_sending()

所以在Cygwin下,我不会看到“发送数据包”的打印输出,直到我在控制台窗口按下回车。按下后,我只会看到一次“发送数据包”,然后再也不会有,直到我再次按下某个键。在原生的Windows Python和Linux上,我每秒都会看到“发送数据包”。

我想在Windows上使用Cygwin版本进行开发,但我开始怀疑它是否真的正常工作。我猜这可能和全局解释器锁(GIL)有关?我还尝试过一个版本,其中发送标志与threading.RLock同步,但这并没有改变行为。

1 个回答

0

如果你还没有更新你的cygwin(版本是cygwin 1.5.5-1+),我觉得可能会有一些关于线程的错误。你可以试着用最新的版本来运行代码,这样可以排除这个问题。

撰写回答