교착 상태 찾기


18

교착 상태 찾기

멀티 스레딩 응용 프로그램을 프로그래밍 할 때는 공유 리소스에 액세스 할 때 다양한 스레드 교착 상태를 피하기 위해주의를 기울여야합니다. 교착 상태 스레드 시도는 다른 스레드가 먼저 잠근 리소스에 액세스하려고하는 동시에 다른 스레드에 잠겨 리소스에 액세스 할 때 발생합니다. 이것은 간단한 경우이지만 더 긴 리소스 체인으로 인해 더 복잡해질 수 있습니다.

도전

각 스레드가 액세스하는 리소스 목록에서 가능한 교착 상태 상황을 감지 할 수있는 프로그램이나 함수를 작성해야합니다. 이것은 코드 골프이므로 바이트 단위의 최단 답변이 이깁니다.

모든 스레드는 동시에 시작되지만 그 후에는 인터리빙의 모든 조합에서 실행될 수 있습니다. 4 개 작업을 각각 2 개 스레드가있는 경우, (각 번호는 해당 ID와 스레드 취한 조치 임)로 실행 될 수있는 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, 또는 다른 가능한 조합.

입력

STDIN을 통해 함수 매개 변수 또는 가장 가까운 대안으로 문자열 목록을 수신합니다. 각 문자열은 형식 +a -b입니다. 이 문자열은 모두 스레드에 의해 리소스 의 잠금 ( +) / 잠금 해제 ( -)를 나타냅니다 . 모든 스레드 사이에는 ---구분 기호 가 있습니다 . 스레드가 이미 잠근 리소스를 잠그려고 시도하지 않으며 모든 스레드가 종료하기 전에 잠근 모든 리소스를 명시 적으로 잠금 해제합니다. 다음은 설명하는 예입니다.

+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

산출

입력에 교착 상태 가능성이 없으면 출력이 거짓이고, 교착 상태 상황이 포함되어 있으면 사실입니다. 예를 들면 다음과 같습니다.

  • true
  • false
  • 1
  • 0

모든 유효한 결과물이지만, 진실 / 거짓으로 명확하게 정의 된 것은 허용됩니다.

+a
-a
---
+a
-a

산출: false


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

산출 true

b,a스레드마다 각각 획득하려고 할 때 교착 상태1,2


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

산출 false


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

산출: true

b,c,a각각 1,2,3 스레드에서 교착 상태가 발생합니다 .


http://pastebin.com/vMYRZxtW

산출 false


http://pastebin.com/V5MVgNgS

산출 true

b,d,a각각 획득하려고 할 때 스레드 1,2,3의 교착 상태 .


물론 이것은 더 많은 스레드, 더 많은 리소스 등으로 인해 훨씬 ​​더 복잡해질 수 있지만 이러한 테스트는 기본 사항을 다루고 있다고 생각합니다.

보너스

프로그램을 작성할 때 교착 상태 상황을 발견하면 매우 슬프기 때문에 각각 출력에 대한 -8 바이트 보너스 :(:)진실 / 거짓으로 보너스가 있습니다.


나는 이것을 가정하고 있지만, 각 스레드의 작업 (스레드의 맨 위에서 시작)이 병렬로 실행되고 동일한 시스템 시간에 해당한다는 것을 분명히하는 것이 좋을 것입니다.
Optimizer

1
작업은 동시에 실행되지만 모든 작업이 실행되는 시간은 가정 할 수 없습니다. 스레드가 실제로 하나씩 차례로 실행되거나 완전히 인터리브 될 수 있습니다. 스레드 1의 전반이 실행 된 다음 스레드 2가 완전히 실행 된 후 스레드 1이 후반에 실행될 수 있습니다. 등등. 명확히하기 위해 질문을 업데이트했습니다.
rorlork

1
아, 괜찮아, 작업은 교착 상태가 가능한지 여부에 관계없이 스레드 실행 시간의 가능한 조합을 고려하는 것입니다.
Optimizer

예, 죄송합니다. 의심 할 여지가 없습니다. 실제로 마지막 예제에서는 스레드 2가 d나중에 리소스를 사용하려고 시도하지 않기 때문에이 방법이 설명 됩니다.
rorlork

1
@ rcrmn 당신 :)은 거짓과 :(진실을 위해해서는 안 됩니까?
Tyilo

답변:


4

파이썬 2-227

기본적으로 '우선 순위'루프가 없는지 확인하십시오. 예를 들어 두 번째 테스트에서 첫 번째 스레드는 a(b)우선 순위를 가지며 두 번째 스레드는 우선 순위를 가지며b(a) 우선 순위를 갖습니다.

필자는 모든 itertools 작업에서 잘 작동한다고 생각하면서 Pyth에서 이것을 다시 작성하려고 생각했지만 정규 표현식을 변환하면 약간의 작업이 필요하므로 지금 게시하고 변환하고 나중에 다른 답변을 게시하려고합니다.

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 그것은 나를 위해 True를 출력합니다; 정확히 어떻게 운영하고 있습니까?
KSab

오, 그것은 나를 위해 한 줄만 읽고있었습니다. 어떻게 운영해야합니까?
Tyilo

@Tyilo 나는 형식을 여러 줄 문자열을 입력으로받는 함수로 변경했다
KSab

5

파이썬 - 586 539 524 501 485 바이트 - 8 = 477

들여 쓰기 수준 :

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
사용 ;문자를 저장 들여 쓰기 라인을 결합합니다. 마찬가지로, 당신의 진술을 하나의 라이너로 만드십시오.
isaacg

@isaacg와 에이스, 감사합니다! 나는 당신의 팁을 사용하여 최대한 향상했다고 생각합니다.
Tyilo

BTW 파일에서 입력을 파이핑하지 않거나 Ctrl + D를 두 번 누르면 신경 쓰지 않아도됩니다. for r in sys.stdin 대신for r in sys.stdin.readlines()
user12205

@ace 나는 단지 사용하는 것 사이에 다른 행동을 보지 못했습니다. sys.stdin 또는 sys.stdin.readlines()내가 다시, 감사를 변경 한 정도.
Tyilo

사이의 공백을 제거 할 수 있습니다 print':)'
user12205
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.