Socket.close()は、そのソケットですでに実行されているsocket.accept()呼び出しをブロックしません。閉じたunixソケットでsocket.accept()を呼び出す
Pythonプログラムには、すでに閉じられているunixドメインソケットでblocking socket.accept()を呼び出すスレッドがいくつかあります。 socket.accept()呼び出しを停止するか、 例外を発生させることによって、これらのスレッドを強制終了します。
私は、プログラムを停止することなく、プログラムに新しいコードをロードすることでこれを実行しようとしています。 したがって、これらのスレッドを生成したコードまたはソケットを閉じたコードを変更することは選択できません。
これを行う方法はありますか?
これはhttps://stackoverflow.com/a/10090348/3084431に似ていますが、これらのソリューションは、私のコードのための作業を習慣:
- この点は真実ではない、閉鎖は受け入れに例外を発生しません。シャットダウンしますが、スレッドが閉じられてもそれを呼び出すことはできません。
- 私はこのソケットにもう接続できません。ソケットが閉じています。
- accept呼び出しのスレッドは既に実行されており、変更できません。明確化のために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'の呼び出しと同時に実行されるとどうなりますか? Pythonのソケットオブジェクトはスレッドセーフではありません。あるスレッドで別のスレッドがアクセスしている間は、そのスレッドの状態を変更することはできません。実行するか、ブロックする準備をするのとは対照的に、 'accept'が確実に実行できるかどうかはまったくありません。だから、これは安全に行うことはできません。 –
@ivan_pozdeevクライアントは存在しません。永久に待機してスレッドが終了しないようにするのは、単に「accept」機能です。 @DavidSchwartz 'sock.close'は' sock.accept'の実行中に実際に実行されます。問題は、ソケットは現在閉じているが、 'sock.accept'はまだ動いているということです。 – Troido