Schreiben Sie den kürzesten Code, um einen Deadlock zu erstellen . Die Codeausführung muss angehalten werden, damit dies nicht funktioniert:
public class DeadlockFail extends Thread{ //Java code
public static void main(String[]a){
Thread t = new DeadlockFail();
t.start();
t.join();
}
//this part is an infinite loop; continues running the loop.
public void run(){while(true){}}
}
Es muss nicht sicher sein, dass der Code in einen Deadlock gerät , nur fast sicher (wenn Sie unendlich lange laufen, wird er einen Deadlock verursachen).
code-golf
concurrency
Justin
quelle
quelle
Code execution must halt
Ich verstehe nicht Wie ist es ein Deadlock, wenn es anhält? Meinst du, es wird auf etwas warten, anstatt nur wie ein Arschloch zu spinnen?Antworten:
Dyalog APL (10)
⎕TSYNC
Lässt den Thread warten, bis der angegebene Thread endet,⎕TID
gibt den aktuellen Thread an.Dyalog APL kann jedoch Deadlocks erkennen und reagiert daher sofort mit
Der Spaß ist, dass Sie nicht einmal zusätzliche Threads erzeugen müssen, sodass es ausreichend ist, den UI-Thread auf sich selbst warten zu lassen.
Wenn dies ein Betrug ist und tatsächlich neue Threads erforderlich sind, können Sie dies in 27 Zeichen tun:
F & x
wirdF
in einem neuen Thread für den Wert ausgeführtx
und gibt die Thread-ID zurück. Damit:{⎕TSYNC⎕TID+1}&0
erstellt einen Thread, der mit dem Thread synchronisiert wird, dessen ID eine höhere als seine eigene ist.⎕TSYNC&
Erstellt einen neuen Thread, der mit dem vorherigen Thread synchronisiert wird und dessen ID höher ist als der gerade erstellte Thread (vorausgesetzt, nichts anderes erstellt Threads).∇
verursacht eine Endlosschleife (also erstellen wir so lange Threads, bis ein Deadlock vorliegt).Dies wird zum Stillstand kommen, sobald der zweite Thread erstellt wird, bevor der erste ausgeführt wird. Dies ist ziemlich bald der Fall:
quelle
⎕TSYNC 0'.
⎕TID` ist0
.Geh, 42
Entschuldigung, Downvoter, dass Sie nicht angegeben haben, wie es funktioniert. Dadurch wird ein anonymer Int-Kanal erstellt und daraus gelesen. Dadurch wird der Hauptthread angehalten, bis ein Wert über den Kanal gesendet wird. Dies geschieht offensichtlich nie, da keine anderen Threads aktiv sind, und führt daher zu einem Deadlock.
quelle
Ruby, 39 Zeichen
Die Idee, einen Cross-Join zu verwenden, wurde schamlos aus Johannes Kuhns Java-Antwort gestohlen .
Wir können vier Zeichen (bis 35 ) rasieren, wenn wir den Code auf eine bestimmte Umgebung abstimmen. JRubys Konsolen-IRB ist Single-Threaded:
Dies ist meine vorherige Lösung:
Es ist einfach, einen Thread auf einen Mutex zu kleben:
Dies ist jedoch kein richtiger Deadlock, da der zweite Thread technisch nicht auf den ersten Thread wartet. "hold and wait" ist laut Wikipedia eine notwendige Voraussetzung für einen Deadlock. Der erste Thread wartet nicht und der zweite Thread enthält nichts.
Rubin,
9795 ZeichenDies ist ein klassischer Deadlock. Zwei Threads konkurrieren um zwei Ressourcen und versuchen es erneut, wenn sie erfolgreich sind. Normalerweise bleiben sie innerhalb einer Sekunde auf meiner Maschine stecken.
Wenn es jedoch in Ordnung ist, unendlich viele Threads zu haben (von denen keiner unendlich viel CPU verbraucht und von denen einige einen Deadlock aufweisen),
Rubin,
8785 ZeichenMeinem Test zufolge schlägt es fehl, nachdem die Thread-Anzahl ungefähr 4700 erreicht hat. Hoffentlich schlägt es nicht fehl, bis jeder Thread eine Chance zum Ausführen hatte (also entweder Deadlocking oder Beenden und Freigeben von Speicherplatz für einen neuen). Laut meinem Test sinkt die Thread-Anzahl nach dem Auftreten des Fehlers nicht, was bedeutet, dass während des Tests ein Deadlock aufgetreten ist. Auch IRB starb nach dem Test.
quelle
o
&p
Variablen? Kannst du nicht einfach passenm
undn
für den neuen Thread?m
undn
sind global. Beide Threads sehen sie in derselben Reihenfolge.o
undp
sind threadlokal (auf die Schleifeniteration beschränkt). Die Verwendungt[...]
würde wahrscheinlich teuer werden, und ich kann keinen besseren Weg sehen, Parameter an den Thread zu übergeben, als über das Schließen. Durch Hinzufügen zusätzlicher Parameter wirdnew
der Code um zwei Zeichen verlängert.T=Thread;T.new{T.main.join}.join
Python, 46
(Selbststillstand)
quelle
from threading import* Semaphore(0).acquire()
ist um ein Byte kürzer, denke ichBash + GNU Coreutils, 11 Bytes
Erstellt ein streunendes FIFO
x
im aktuellen Verzeichnis (Sie müssen also keine Datei mit diesem Namen haben). FIFOs können wie normale Dateien gelöscht werden, daher sollte es nicht schwierig sein, sie zu löschen.Ein FIFO hat eine Schreibseite und eine Leseseite; Der Versuch, einen Block zu öffnen, bis ein anderer Prozess den anderen öffnet, scheint absichtlich als Synchronisationsprimitiv konzipiert worden zu sein. Da es hier nur einen Thread gibt,
<x
bleiben wir stecken , sobald wir versuchen, ihn zu öffnen . (Sie können den Deadlock lösen, indem Sie aus einem anderen Prozess in das betreffende FIFO schreiben.)Dies ist eine andere Art von Deadlock als bei zwei Ressourcen, und zwei Threads haben jeweils eine und benötigen die andere. In diesem Fall gibt es keine Ressourcen, und der Prozess benötigt eine. Aufgrund der anderen Antworten denke ich, dass dies zählt, aber ich kann verstehen, wie ein Deadlock-Purist die Antwort möglicherweise ablehnen möchte.
Wenn ich darüber nachdenke, kann ich mir tatsächlich drei Deadlock-ähnliche Situationen vorstellen:
Der "traditionelle" Deadlock: Zwei Threads warten jeweils darauf, dass eine Sperre aufgehoben wird, die vom anderen Thread gehalten wird.
Ein einzelner Thread wartet darauf, dass eine Sperre freigegeben wird, hält jedoch die Sperre selbst (und blockiert sich somit selbst, um sie freizugeben).
Ein einzelner Thread wartet darauf, dass ein Synchronisationsprimitiv freigegeben wird, aber das Synchronisationsprimitiv startet in einem natürlich gesperrten Zustand und muss extern entsperrt werden, und dafür wurde nichts programmiert.
Dies ist ein Deadlock vom Typ 3, der sich grundlegend von den beiden anderen unterscheidet: Sie könnten theoretisch ein Programm schreiben, um das betreffende Synchronisationsprimitiv zu entsperren, und es dann ausführen. Wie gesagt, das gleiche gilt für Deadlocks vom Typ 1 und 2, da viele Sprachen ermöglichen es Ihnen , eine Sperre lösen Sie nicht selbst tun (du bist nicht angenommen zu und würde keinen Grund , dies zu tun , wenn Sie einen Grund hatte, benutze zuerst die Schlösser, aber es funktioniert…). Es lohnt sich auch, ein Programm wie
mkfifo x;<x;echo test>x
;; Dieses Programm ist das Gegenteil eines Deadlocks vom Typ 2 (es versucht, beide Enden des FIFO zu öffnen, aber es kann ein Ende erst öffnen, nachdem es das andere Ende geöffnet hat), aber es wurde aus diesem Ende durch Hinzufügen von Extra erstellt Code, der nie nach diesem läuft! Ich denke, das Problem ist, dass es von der Absicht hinter der Verwendung des Schlosses abhängt, ob ein Schloss blockiert ist oder nicht. Daher ist es schwierig, objektiv zu definieren (insbesondere in einem Fall wie diesem, in dem der einzige Zweck des Schlosses darin besteht, absichtlich einen Deadlock zu erzeugen ).quelle
C #, 100
Siehe: Der No-Lock-Deadlock
quelle
static C
nach verschiebenMain
?Bash mit Glibc, 6 Bytes
Es tut mir leid, einen alten Thread wiederzubeleben, aber ich konnte nicht widerstehen.
Als Wurzel:
Vom Mann pldd :
quelle
Java, 191
Ungolfed:
Startet einen neuen Thread und
join
darauf (warten Sie, bis dieser Thread beendet ist), während der neue Thread dasselbe mit dem ursprünglichen Thread tut.quelle
Error
statt wirfst und fängstException
?Thread.join()
wirft eineInteruptedException
, die keine Unterklasse von istError
.Tcl, 76
Sackgasse.
Dadurch wird ein neuer Thread erstellt und der andere Thread wird angewiesen, meinem Thread eine Nachricht zu senden (Skript zum Ausführen).
Das Senden einer Nachricht an einen anderen Thread wird jedoch normalerweise blockiert, bis das Skript ausgeführt wurde. Und während es blockiert, werden keine Nachrichten verarbeitet, sodass beide Threads darauf warten, dass der andere ihre Nachricht verarbeitet.
quelle
thread::send
Stellt ein Skript in die Warteschlange, das in einem anderen Thread ausgeführt werden soll, und wartet, bis es abgeschlossen ist. Am Ende warten also Thread 1 auf Thread 2 und Thread 2 auf Thread 1.Alternative Java mit Monitor-Missbrauch (248 Charas)
quelle
Scala, 104 Bytes
Der Lazy-Val-Initialisierungsblock wird angehalten, bis eine Bedingung erfüllt ist. Diese Bedingung kann nur durch Lesen des Werts von Lazy Val x erfüllt werden - ein anderer Thread, der diese Bedingung erfüllen soll, kann dies nicht. Somit wird eine zirkuläre Abhängigkeit gebildet, und das Lazy Val kann nicht initialisiert werden.
quelle
Kotlin, 35/37/55 Bytes
Allgemeines Thema :
Thread.currentThread().join()
.Mit Ausnahme von JVM-Fehlern / sehr spezialisiertem Code gegen diese Übermittlung sollte dies niemals zurückkehren, da der aktuelle Ausführungsthread jetzt deaktiviert ist und darauf wartet, dass er selbst stirbt.
Böse Eigenschaft: 35 Bytes (nicht konkurrierend): 35 Bytes
val a=Thread.currentThread().join()
Wenn Sie dies an einer beliebigen Stelle platzieren, an der eine Eigenschaftsdeklaration gültig ist, wird derjenige blockiert, der sie initialisiert. Im Fall einer Eigenschaft der obersten Ebene ist dies der Klassenladeprogramm, das die zugeordnete JVM-Klasse für diese Datei initialisiert (standardmäßig
[file name]Kt.class
).Nicht konkurrierend, weil "dies überall als Top-Level-Eigenschaft platzieren" restriktiv ist.
Funktion: 37 Bytes
fun a()=Thread.currentThread().join()
main (): 55 Bytes
fun main(a:Array<String>)=Thread.currentThread().join()
quelle
PowerShell,
362823 ByteSelbststillstand. Wir bekommen alle Prozesse mit
Get-Process
und warten dann geduldig darauf, dass jeder von ihnen beendet wird ... was ungefähr nie passieren wird, da der Prozess auf sich selbst wartet.Bearbeiten - 5 Bytes dank Roman Gräf gespeichert
quelle
(gps)|%{$_.waitforexit()}
ist drei Bytes kürzer und wartet, bis alle Prozesse beendet sind.gps
in diesem Fall nicht, also insgesamt 5 Bytes gespart.C (nur Linux), 31 Bytes - Probieren Sie es online aus!
Der Systemaufruf 240 (0xf0) ist Futex (2) oder schneller Benutzerbereich-Mutex. Die Dokumentation besagt, dass das erste Argument ein Zeiger auf den Futex ist, das zweite Argument die Operation (0 bedeutet FUTEX_WAIT, dh warten, bis ein anderer Thread den Futex entsperrt). Das dritte Argument ist der Wert, den der Futex erwartet, solange er noch gesperrt ist, und das vierte Argument ist der Zeiger auf das Zeitlimit (NULL für kein Zeitlimit).
Da es keinen anderen Thread gibt, um den Futex freizuschalten, wird er offensichtlich für immer in einem selbstverschuldeten Deadlock warten. Es kann überprüft werden (über
top
oder einen anderen Task-Manager), dass der Prozess keine CPU-Zeit benötigt, wie wir es von einem blockierten Thread erwarten sollten.quelle
Julia 0,6 , 13 Bytes
Sprache neuer als Frage. Warten Sie auf eine Aufgabe (wie eine Go-Routine, die sich derzeit im selben Thread befindet, in zukünftigen Versionen von Julia möglicherweise in einem anderen Thread), deren Ausführung nicht geplant ist.
Probieren Sie es online aus!
quelle
BotEngine, 3x3 = 9 (9 Bytes)
Schritt 5 endet damit, dass zwei Bots auf unbestimmte Zeit darauf warten, dass sie sich bewegen ... ein Bot kann sich nicht bewegen, weil er darauf wartet, dass sich der andere aus dem unteren rechten Feld herausbewegt, und der andere Bot kann sich nicht bewegen, weil er auf den wartet Erster Bot, der sich aus dem unteren mittleren Quadrat herausbewegt.
quelle
Das Wasserfallmodell (Ratiofall), 13 Bytes
Probieren Sie es online aus!
Hier ist eine lustige Antwort von der Wand. Dies ist die einfachste Endlosschleife im Wasserfallmodell (Variablen im Wasserfallmodell werden wiederholt dekrementiert, wenn nichts anderes passiert; dieses Programm definiert eine Variable, die sich bei jedem Dekrementieren inkrementiert, sodass niemals etwas passieren kann).
Die Frage fragt nach einem Deadlock, nicht nach einer Endlosschleife. Wir können jedoch das Verhalten bestimmter Implementierungen ausnutzen. Bei Optimierungsstufe 2 oder höher (die Standardeinstellung ist 3) erkennt der Interpreter Ratiofall die Endlosschleife und optimiert sie… in einen Deadlock! Zumindest wenn wir Sprachen als durch ihre Implementierung definiert betrachten (was normalerweise auf dieser Site der Fall ist), definiert dieses Programm tatsächlich eher einen Deadlock als eine Endlosschleife.
Sie können Hinweise auf den Deadlock aus dem Zeitbericht auf Try it Online! Link oben:
Das Programm lief 60 Sekunden lang (bis TIO es automatisch beendete), aber die meiste Zeit gab es keine CPU-Auslastung, keine Zeit, die vom Programm ausgeführt wurde, und keine Zeit, die der Kernel für das Programm verbrachte.
Um noch stärkere Beweise zu erhalten, können Sie Ratiofall unter einem Debugger auf Systemaufrufebene ausführen, z
strace
. Wenn Sie dies unter Linux tun, wird der Interpreter bei einemfutex
Systemaufruf blockiert , der versucht, eine Sperre zu aktivieren, die niemals freigegeben wird.quelle
Perl 6 , 24 Bytes
Probieren Sie es online aus!
Erstellen Sie ein Semaphor mit null Genehmigungen und versuchen Sie dann, es zu erwerben.
quelle