Использование: sock.shutdown (socket.SHUT_RD)
Тогда accept
вернется EINVAL
. Никаких уродливых сигналов поперечной резьбы не требуется!
Из документации Python: «Примечание close()
освобождает ресурсы, связанные с подключением, но не обязательно закрыть соединение немедленно Если вы хотите, чтобы закрыть соединение своевременным способом, называют shutdown()
перед close()
.»
http://docs.python.org/3/library/socket.html#socket.socket.close
Я столкнулся с этой проблемой лет назад, в то время как программирование на C. Но я только нашел решение сегодня, после запуска в ту же самую проблему в Python, и обдумывая, используя сигналы (Тьфу!), И ТОГДА вспомнив записку о shutdown
!
Что касается комментариев, которые говорят, что вы не должны закрывать/использовать сокеты по потокам ... в CPython блокировка глобального интерпретатора должна защищать вас (при условии, что вы используете файловые объекты, а не сырые целочисленные дескрипторы файлов).
Вот пример кода:
import socket, threading, time
sock = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt (socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind (('', 8000))
sock.listen (5)
def child():
print ('child accept ...')
try: sock.accept()
except OSError as exc : print ('child exception %s' % exc)
print ('child exit')
threading.Thread (target = child).start()
time.sleep (1)
print ('main shutdown')
sock.shutdown (socket.SHUT_RD)
time.sleep (1)
print ('main close')
sock.close()
time.sleep (1)
print ('main exit')
+1 Я думаю, последний сценарий. Тема 1 блокирует принятие. Поток 2 закрывает гнездо. Thread1 блокируется навсегда. – Duck
Это правильно. Обратите внимание, что вы, вероятно, захотите установить пустой обработчик сигнала для используемого сигнала. – caf
О, эта часть POSIX действительно сосет. – thodg