ค้นหา Deadlock


18

ค้นหา Deadlock

เมื่อโปรแกรมมิงแบบมัลติเธรดต้องใช้ความระมัดระวังเพื่อหลีกเลี่ยงการล็อคเธรดต่าง ๆ เมื่อเข้าถึงทรัพยากรที่ใช้ร่วมกัน การหยุดชะงักเกิดขึ้นเมื่อเธรดพยายามเข้าถึงทรัพยากรที่ถูกล็อคในเธรดอื่นในเวลาเดียวกันกับที่เธรดอื่นกำลังพยายามเข้าถึงทรัพยากรที่ถูกล็อคโดยเธรดแรก นี่เป็นกรณีที่ง่าย แต่อาจมีความซับซ้อนมากขึ้นด้วยโซ่ทรัพยากรที่ยาวขึ้น

ความท้าทาย

คุณควรเขียนโปรแกรมหรือฟังก์ชั่นที่สามารถตรวจจับสถานการณ์การหยุดชะงักที่เป็นไปได้ในรายการทรัพยากรที่เข้าถึงได้โดยแต่ละเธรด นี่คือ code-golf ดังนั้นคำตอบที่สั้นที่สุดในหน่วยไบต์ชนะ

ทุกเธรดเริ่มต้นในเวลาเดียวกัน แต่หลังจากนั้นเธรดสามารถทำงานร่วมกันได้ หากมี 2 หัวข้อ 4 การกระทำของแต่ละคนก็อาจจะทำงานเป็น (ที่แต่ละหมายเลขเป็นการกระทำที่เกิดจากด้ายกับว่า 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

การหยุดชะงักในเธรด 1,2,3 เมื่อพยายามรับb,c,aตามลำดับ


http://pastebin.com/vMYRZxtW

เอาท์พุต false


http://pastebin.com/V5MVgNgS

เอาท์พุต true

การหยุดชะงักในเธรด 1,2,3 เมื่อพยายามรับb,d,aตามลำดับ


แน่นอนว่าสิ่งนี้อาจมีความซับซ้อนมากขึ้นโดยมีเธรดมากขึ้นทรัพยากรเพิ่มเติมสำหรับแต่ละรายการและอื่น ๆ แต่ฉันเชื่อว่าการทดสอบเหล่านี้ครอบคลุมพื้นฐาน

โบนัส

เนื่องจากเป็นเรื่องที่น่าเศร้ามากเมื่อคุณพบสถานการณ์การหยุดชะงักเมื่อเขียนโปรแกรมจึงมีโบนัส -8 ไบต์เพื่อตอบสนองการแสดงผล:(และ:)เป็นความจริง / เท็จตามลำดับ


ฉันแค่สมมติว่านี้ แต่จะเป็นการดีที่จะชี้แจงว่าการกระทำของแต่ละเธรด (เริ่มต้นจากด้านบนของเธรด) นั้นทำงานแบบขนานและสอดคล้องกับเวลาของระบบเดียวกัน
เครื่องมือเพิ่มประสิทธิภาพ

1
การดำเนินการจะถูกเรียกใช้พร้อมกัน แต่ไม่สามารถสันนิษฐานได้ว่าเวลาที่ทุกการกระทำนั้นมีการดำเนินการใด อาจเป็นไปได้ว่าเธรดจะถูกเรียกใช้อย่างใดอย่างหนึ่งจริง ๆ หลังจากเธรดอื่นหรือ interleaved สมบูรณ์ อาจเป็นไปได้ว่าในช่วงครึ่งแรกของเธรด 1 ถูกรันจากนั้นเธรด 2 จะถูกรันโดยสิ้นเชิงจากนั้นเธรด 1 จะรันในช่วงครึ่งหลัง และอื่น ๆ ฉันได้อัปเดตคำถามเพื่อให้ความกระจ่าง
rorlork

1
อ่าโอเคดังนั้นงานคือการคิดว่ามีการรวมกันของเวลารันเธรดที่เป็นไปได้ไม่ว่าจะเป็นการหยุดชะงักหรือไม่
เครื่องมือเพิ่มประสิทธิภาพ

ใช่ขอโทษฉันไม่คิดว่าจะทำให้เกิดข้อสงสัย ที่จริงแล้วในตัวอย่างสุดท้ายสิ่งนี้แสดงให้เห็นเนื่องจาก thread 2 ไม่ได้พยายามใช้ทรัพยากรdจนกระทั่งในภายหลัง
rorlork

1
@rcrmn คุณแน่ใจว่า:)ไม่ควรเป็นเท็จและ:(จริงหรือ?
Tyilo

คำตอบ:


4

Python 2 - 227

โดยพื้นฐานแล้วทำให้แน่ใจว่าไม่มี 'ห่วง' มาก่อน ตัวอย่างเช่นในการทดสอบที่สองเธรดแรกมีa(b)ลำดับความสำคัญและเธรดที่สองมีb(a)ความสำคัญ

ฉันคิดเกี่ยวกับการเขียนใหม่นี้ใน Pyth เนื่องจากฉันคิดว่ามันจะทำงานได้ดีกับการทำงานของ itertools ทั้งหมด แต่การแปลง regex จะใช้งานบางอย่างดังนั้นตอนนี้ฉันจะโพสต์สิ่งนี้และอาจลองแปลงมันแล้วโพสต์คำตอบอื่นในภายหลัง

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))

คำตอบนี้เป็นเท็จเพื่อpastebin.com/V5MVgNgS
Tyilo

@Tyilo มันออกจริงสำหรับฉัน; คุณทำงานยังไงกันแน่?
KSab

โอ้มันอ่านแค่บรรทัดเดียวให้ฉัน คุณควรจะใช้มันอย่างไร?
Tyilo

@Tyilo ฉันเปลี่ยนรูปแบบเป็นฟังก์ชั่นที่ใช้สตริงหลาย
บรรทัด

5

Python - 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 และ ace ขอบคุณ! ฉันคิดว่าฉันปรับปรุงมันให้มากที่สุดเท่าที่จะทำได้โดยใช้เคล็ดลับของคุณ
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.