Использование: sock.shutdown (socket.SHUT_RD)
Тогда accept
вернется EINVAL
. Никаких уродливых перекрестных сигналов не требуется!
Из документации Python:
«Примечание close()
освобождает ресурс, связанный с соединением, но не обязательно немедленно закрывает соединение. Если вы хотите закрыть соединение своевременно, позвоните shutdown()
до close()
.»
http://docs.python.org/3/library/socket.html#socket.socket.close
Я столкнулся с этой проблемой несколько лет назад, когда программировал на C. Но я нашел решение сегодня только после того, как столкнулся с той же проблемой в Python, И размышлял, используя сигналы (чёрт!), И ПОТОМ вспомнил заметку о * 1016. *!
Что касается комментариев, в которых говорится, что вы не должны закрывать / использовать сокеты между потоками ... в 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')