Socket.close()는 소켓에서 이미 실행중인 blocking socket.accept() 호출을 차단하지 않습니다.닫힌 유닉스 소켓에서 socket.accept()를 호출
파이썬 프로그램에 이미 닫혀있는 유닉스 도메인 소켓에서 blocking socket.accept() 호출 만 실행하는 여러 스레드가 있습니다. socket.accept() 호출을 중지 시키거나 예외를 발생시켜 이러한 스레드를 종료하려고합니다.
프로그램을 중단하지 않고 프로그램에 새 코드를로드하여이 작업을 수행하려고합니다. 따라서 이러한 스레드를 생성하거나 소켓을 닫은 코드를 변경하는 것은 옵션이 아닙니다.
이렇게 할 방법이 있습니까?
이 https://stackoverflow.com/a/10090348/3084431 유사하지만,이 솔루션은 내 코드에 대한 작업을 실 거예요 :
- 이 점은 사실이 아니다, 폐쇄는 동의에 예외를 발생하지 않습니다. shutdown하지만 스레드가 닫힐 때 더 이상 호출 할 수 없습니다.
- 더 이상이 소켓에 연결할 수 없습니다. 소켓이 닫혔습니다.
- 수락 호출이있는 스레드가 이미 실행 중이므로 변경할 수 없습니다.
- 같은 설명에 대한
3, 나는이 문제를 가지고 몇 가지 예제 코드를 작성했습니다. 이 코드는 작동 모두 파이썬 2와 파이썬 3
import socket
import threading
import time
address = "./socket.sock"
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.bind(address)
sock.listen(5)
def accept():
print(sock.accept())
t = threading.Thread(target=accept, name="acceptorthread")
t.start()
sock.close()
time.sleep(0.5) # give the thread some time to register the closing
print(threading.enumerate()) # the acceptorthread will still be running
내가해야 할 것은이 코드가 어떻게 든 셉터 스레드를 중지 할 수 있습니다 완료 후 내가 실행할 수있는 무언가이다.
재고 소켓 문제는 무엇입니까? 'accept'가 "이미 실행 중"이라면, 새로운 연결을 수락하지 않기 전에 기술적으로 연결이 허용되었습니다. - 그래도 괜찮습니다. 모든 기존 클라이언트를 걷어차 고 싶다면 그렇게해야합니다. –
당신은 결코이 일을 할 수 없을 것입니다. 당신의 코드는 이미 심각한 경쟁 조건을 가지고 있습니다 -'sock.close()'가'accept' 호출과 동시에 실행되면 어떻게 될까요? 파이썬의 소켓 객체는 스레드로부터 안전하지 못합니다. 다른 스레드가 스레드에 액세스하는 동안 한 스레드에서 상태를 수정할 수 없습니다. 실행하거나 차단할 준비가되는 것과는 반대로,'accept'가 실행 중인지를 확인할 수있는 방법은 절대적으로 없습니다. 따라서이 일은 안전하게 할 수 없습니다. –
@ivan_pozdeev 클라이언트가 없다. 영원히 기다리고 스레드가 끝나지 못하도록 차단하는 'accept' 함수 일 뿐이다. @DavidSchwartz'sock.close'는'sock.accept'가 실행되는 동안 실제로 실행됩니다. 문제는 소켓이 닫혀 있지만 여전히'sock.accept'가 실행되고 있다는 것입니다. – Troido