Kilitlenmeyi Bulma


18

Kilitlenmeyi Bulma

Çok iş parçacıklı bir uygulamayı programlarken, paylaşılan kaynaklara erişirken çeşitli iş parçacıklarının kilitlenmesini önlemek için çok dikkatli olunmalıdır. Bir iş parçacığı, diğer iş parçacığının birincisi tarafından kilitlenen bir kaynağa erişmeye çalıştığı sırada başka bir iş parçacığında kilitlenen bir kaynağa erişmeye çalıştığında bir kilitlenme oluşur. Bu basit bir durumdur, ancak daha uzun kaynak zincirleriyle daha karmaşık hale gelebilir.

Meydan okuma

Her iş parçacığının eriştiği kaynaklar listesine olası bir kilitlenme durumunu algılayabilen bir program veya işlev yazmalısınız. Bu kod golf, bayt en kısa cevap kazanır.

Her iş parçacığı aynı anda başlatılır, ancak bundan sonra herhangi bir serpiştirme kombinasyonunda çalışabilirler. 4 işlemlerden her biri 2 parçacığı vardır, (her numara, bu numara ile parçacığı tarafından yapılan bir işlem olduğu) olarak çalıştırılabilir 1,1,1,1,2,2,2,2, 2,2,2,2,1,1,1,1, 1,2,1,2,1,2,1,2, 1,1,2,2,2,2,1,1, ya da herhangi bir başka olası kombinasyon.

Giriş

STDIN, function parametresi veya en yakın alternatif olarak bir dize listesi alırsınız. Her dize formatta olacaktır +a -b. Bu dizelerin her biri, bir kaynağın iş parçacığı tarafından kilitlenmesini ( +) / kilidini açmayı ( -) temsil eder . Her iş parçacığı arasında bir ---ayırıcı olacaktır . Bir iş parçacığının zaten kilitli olduğu bir kaynağı kilitlemeye çalışmadığı ve tüm iş parçacıklarının çıkmadan önce kilitledikleri tüm kaynakların kilidini açıkça açacağı garanti edilir. Aşağıda gösterilebilecek bir örnek verilmiştir:

+a    # Lock resource a
+b    # Lock resource b
-a    # Unlock resource a
-b    # Unlock resource b
---   # Thread separator
+b    # Lock resource b
-b    # Unlock resource b

Çıktı

Girdi herhangi bir kilitlenme olasılığı içermiyorsa çıktı hatalı ve olası bir kilitlenme durumu içeriyorsa doğrudur. Örneğin:

  • true
  • false
  • 1
  • 0

hepsi geçerli çıktılardır, ancak açık / doğru olarak tanımlanan herhangi bir şey kabul edilecektir.

Örnekler

+a
-a
---
+a
-a

Çıktı: false


+a
+b
-b
-a
---
+b
+a
-a
-b

Çıktı true

İş b,aparçacıkları için sırasıyla edinmeye çalışırken kilitlenme1,2


+a
+b
-a
-b
---
+a
+b
-b
-a

Çıktı false


+a
+b
-b
-a
---
+b
+c
-c
-b
---
+c
+a
-a
-c

Çıktı: true

b,c,aSırasıyla elde etmeye çalışırken dişlilerin 1,2,3 kilitlenmesi .


http://pastebin.com/vMYRZxtW

Çıktı false


http://pastebin.com/V5MVgNgS

Çıktı true

Akarsu olmaya çalışırken b,d,asırasıyla 1,2,3 ipliklerinde kilitlenme .


Tabii ki bu çok daha karmaşık hale gelebilir, daha fazla iplik, her biri için daha fazla kaynak ve benzeri, ancak bu testlerin temelleri kapsadığına inanıyorum.

Bonus

Bir program yazarken kilitlenme durumları bulduğunuzda çok üzücü olduğu için , çıktıları yanıtlamak için sırasıyla -8 bayt bonusu vardır :(ve :)sırasıyla doğru / falsy olarak bulunur.


Ben sadece bunu kabul ediyorum, ama her bir iş parçacığının eylemleri (iş parçacığının üstünden başlayarak) paralel olarak çalıştırıldığını ve aynı sistem zamanına karşılık geldiğini açıklığa kavuşturmak güzel olurdu
Optimizer

1
Eylemler eşzamanlı olarak yürütülür, ancak her eylemin yürütüldüğü zaman kabul edilemez. İpliklerin birbiri ardına kesin olarak veya tamamen serpiştirilmiş olması mümkündür. İplik 1'in ilk yarısının çalıştırılması, daha sonra iplik 2 tamamen çalıştırılması, ardından iplik 1'in ikinci yarısı çalıştırılması olabilir. Ve bunun gibi. Soruyu açıklığa kavuşturmak için güncelledim.
rorlork

1
Ah tamam, öyleyse, iş parçacığı çalışma sürelerinin olası bir birleşimi verildiğinde, bir kilitlenmenin mümkün olup olmadığını anlamaktır.
Doktor,

Evet, üzgünüm, bunun şüphe bırakabileceğini düşünmedim. Aslında son örnekte, iş parçacığı 2 ddaha sonraya kadar kaynak kullanmaya çalışmadığı için bu gösterilmiştir .
rorlork

1
@rcrmn :)yanlış ve :(doğru olmadığından emin misin ?
Tyilo

Yanıtlar:


4

Python 2-2227

Temelde 'öncelik' döngüsü olmadığından emin olur. Örneğin, ikinci testte, birinci iplik bir a(b)önceliğe ve ikinci iplik bir b(a)önceliğe sahiptir.

Ben bütün iteri araçları operasyonları ile iyi çalışacağını düşünüyorum gibi Pyth bunu yeniden yazma düşünüyordum, ama regex dönüştürmek için biraz iş alacak bu yüzden ben bu yazı ve belki dönüştürmek ve daha sonra başka bir cevap sonrası çalışacağız.

from itertools import*
import re
f=lambda t:any(re.search(r"(.)((.)\3)+\1",''.join(p))for i in product(*[[m.group(1)+m.group(2)for m in re.finditer(r"(\w).*(\w).*\2.*\1",e,16)]for e in t.split('---')])for p in permutations(i))


@Tyilo Benim için doğru çıktı; tam olarak nasıl çalıştırıyorsun?
KSab

benim için sadece bir satır okuyordu. Nasıl çalıştırman gerekiyor?
Tyilo

@Tyilo Biçimi girdi olarak çok satırlı bir dize alan bir işlev olarak değiştirdim
KSab

5

Python - 586 539 524 501 485 bayt - 8 = 477

Girinti seviyeleri:

1: 1 space
2: 1 tab
3: 1 tab + 1 space
4: 2 tabs

-

import sys
V=set()
t=[[[]]]
for r in sys.stdin:
 r=r.strip()
 if'---'==r:t.append([[]])
 else:v=r[1:];V.add(v);l=t[-1][-1];t[-1].append(l+[v]if'+'==r[0]else filter(lambda x:x!=v,l))
s=lambda l:s(l[1:])+map(lambda x:(l[0],x),l[1:])if 1<len(l)else[]
E=reduce(set.union,map(lambda x:set(sum(map(s,x),[])),t),set())
for v in V:
 k=set();q=[v]
 while 0<len(q):
    u=q.pop(0)
    if u in k:continue
    k.add(u)
    for x,y in E:
     if u==x:
        if y in k:print':(';sys.exit()
        else:q.append(y)
print':)'

1
;Karakterleri kaydetmek için girintili satırları birleştirmek için kullanın . Benzer şekilde, ifadelerinizi bir astar haline getirin.
isaacg

@isaacg ve ace, Teşekkürler! Sanırım ipuçlarını kullanabildiğim kadar geliştirdim.
Tyilo

BTW Bir dosyadan girişi borulamaya aldırmazsanız (veya Ctrl + D'ye iki kez for r in sys.stdinfor r in sys.stdin.readlines()
basarsanız)

@ace adil kullanma ile farklı bir davranış görmüyorum sys.stdinveya sys.stdin.readlines()değiştirdim, tekrar teşekkürler
Tyilo

printVe':)'
user12205
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.