Рубин, 39 знаков
T=Thread;t=T.current;T.new{t.join}.join
Идея использовать кросс-соединение, бесстыдно украденное из Java-ответа Йоханнеса Куна .
Мы можем сбрить четыре символа (до 35 ), если настроим код для конкретной среды. IRB консоли JRuby является однопоточным:
T=Thread;T.new{T.list[0].join}.join
Это мое предыдущее решение:
завести поток на мьютекс легко:
m=Mutex.new;2.times{Thread.new{m.lock}}
но это не правильный тупик, потому что второй поток технически не ждет первого потока. «Держи и жди» - это необходимое условие тупика, согласно Википедии. Первый поток не ждет, а второй поток не содержит ничего.
Рубин, 97 95 персонажей
m,n=Mutex.new,Mutex.new
2.times{o,p=(m,n=n,m)
Thread.new{loop{o.synchronize{p.synchronize{}}}}}
это классический тупик. Два потока конкурируют за два ресурса, повторяя попытку в случае успеха. Обычно они застряли в течение секунды на моей машине.
Но если с бесконечным количеством потоков (ни один из которых не потребляет ЦП бесконечно, а некоторые из которых тупик), то все в порядке,
Рубин, 87 85 символов
m,n=Mutex.new,Mutex.new
loop{o,p=(m,n=n,m)
Thread.new{o.synchronize{p.synchronize{}}}}
Согласно моему тесту, он терпит неудачу после того, как число потоков достигает примерно 4700. Надеемся, что оно не будет работать до тех пор, пока у каждого потока не будет возможности запустить (таким образом, либо взаимная блокировка, либо завершение и освобождение места для нового). Согласно моему тесту, количество потоков не падает после возникновения ошибки, то есть во время теста возникла взаимоблокировка. Также ИРБ умерла после теста.