Python-Timeout-Kontextmanager mit Threads

8

Ich habe timeout context manager, das perfekt mit Signalen funktioniert, aber es erhöht den Fehler im Multithread-Modus, da Signale nur im Haupt-Thread funktionieren.

%Vor%

Ich habe die Decorator-Implementierung von timeout gesehen, aber ich weiß nicht, wie ich yield innerhalb der Klasse weitergeben kann, die von threading.Thread abgeleitet ist. Meine Variante wird nicht funktionieren.

%Vor%     
San4ez 22.02.2013, 06:54
quelle

4 Antworten

9

Wenn der vom Context-Manager geschützte Code schleifenbasiert ist, sollten Sie die Behandlung von Thread-Kills in Betracht ziehen. Das Töten eines anderen Threads ist in der Regel unsicher. Daher besteht die Standardmethode darin, dass der steuernde Thread ein Flag setzt, das für den Arbeitsthread sichtbar ist. Der Worker-Thread überprüft dieses Flag regelmäßig und schließt sich selbst sauber ab. So können Sie etwas analoges zu Timeouts machen:

%Vor%

Hier ist ein Beispiel für eine single-threaded Verwendung:

%Vor%

und eine Multithread-Version:

%Vor%

Dieser Ansatz ist aufdringlicher als die Verwendung von Signalen, aber er funktioniert für beliebige Threads.

    
Mr Fooz 03.03.2013 20:12
quelle
3

Ich kann nicht sehen, wie Sie mit einem Kontextmanager vorgehen, was Sie vorschlagen. Sie können yield nicht von einem Thread zum anderen leiten. Was ich tun würde, ist Ihre Funktion mit einem interguable Thread mit dem Timeout zu umhüllen. Hier ist ein Rezept dafür.

Sie werden einen zusätzlichen Thread haben und die Syntax wird nicht so gut sein, aber es würde funktionieren.

    
barracel 26.02.2013 02:05
quelle
0

Ich weiß, dass es spät ist, aber ich lese gerade erst, aber was ist mit der Erstellung eines eigenen Signal- / Kontextmanagers? Ich bin neu bei Python würde gerne Feedback von erfahrenen Entwicklern diese Implementierung.

Dies basiert auf der Antwort von "Mr. Fooz"

%Vor%

Anwendungsfall:

%Vor%     
Damel Lambert-Powell 06.07.2017 12:05
quelle
-2

Timeouts für Systemaufrufe erfolgen mit Signalen. Die meisten blockierenden Systemaufrufe kehren mit EINTR zurück, wenn ein Signal auftritt, so dass Sie Alarme verwenden können, um Timeouts zu implementieren.

Hier ist ein Kontext-Manager, der mit den meisten Systemaufrufen arbeitet und bewirkt, dass IOError von einem blockierenden Systemaufruf ausgelöst wird, wenn es zu lange dauert.

%Vor%     
six face 22.02.2013 06:57
quelle