ความปลอดภัยของเธรดสามารถให้บริการได้อย่างไรโดยภาษาการเขียนโปรแกรมคล้ายกับวิธีที่ความปลอดภัยของหน่วยความจำมีให้โดย Java และ C #


10

Java และ C # ให้ความปลอดภัยของหน่วยความจำโดยการตรวจสอบขอบเขตของอาเรย์และตัวชี้ dereferences

กลไกใดที่สามารถนำไปใช้กับภาษาโปรแกรมเพื่อป้องกันความเป็นไปได้ของสภาพการแข่งขันและการหยุดชะงัก


3
คุณอาจสนใจในสิ่งที่ Rust ทำ:
Vincent Savard

2
ทำให้ทุกอย่างไม่เปลี่ยนรูปหรือทำทุกอย่างให้ตรงกันด้วยช่องทางที่ปลอดภัย นอกจากนี้คุณอาจจะสนใจในการไปและErlang
ธีรโรจน์

@Theraot "ทำทุกอย่างให้ตรงกันด้วยช่องทางที่ปลอดภัย" - หวังว่าคุณจะสามารถอธิบายรายละเอียดให้ดีได้
mrpyo

2
@mrpyo คุณจะไม่เปิดเผยกระบวนการหรือเธรดการโทรทุกครั้งเป็นคำสัญญาทุกอย่างทำงานไปพร้อม ๆ กัน (ด้วยการกำหนดเวลารันไทม์สำหรับการดำเนินการและการสร้าง / รวมเธรดระบบเบื้องหลังตามความจำเป็น) และตรรกะที่ปกป้องสถานะอยู่ในกลไก ที่ส่งผ่านข้อมูลรอบ ๆ ... รันไทม์สามารถทำให้เป็นอันดับโดยอัตโนมัติโดยการตั้งเวลาและจะมีห้องสมุดมาตรฐานที่มีโซลูชั่นเธรดที่ปลอดภัยสำหรับพฤติกรรมที่แตกต่างกันมากขึ้นโดยเฉพาะอย่างยิ่งผู้ผลิต / ผู้บริโภคและการรวมตัวมีความจำเป็น
ธีระโรจน์

2
โดยวิธีการที่มีวิธีการที่เป็นไปได้อื่น: หน่วยความจำในการทำธุรกรรม
ธีระโรจน์

คำตอบ:


14

การแข่งขันเกิดขึ้นเมื่อคุณมีนามแฝงพร้อมกันของวัตถุและอย่างน้อยหนึ่งนามแฝงกำลังกลายพันธุ์

ดังนั้นเพื่อป้องกันการแข่งขันคุณต้องทำอย่างน้อยหนึ่งเงื่อนไขเหล่านี้ไม่เป็นความจริง

วิธีการที่หลากหลายจัดการกับแง่มุมต่าง ๆ ฟังก์ชั่นการเขียนโปรแกรมเน้นความไม่เปลี่ยนรูปซึ่งจะขจัดความไม่แน่นอน การล็อค / atomics ลบความพร้อมกัน ประเภท Affine ลบนามแฝง (สนิมลบนามแฝงที่ไม่แน่นอน) ดารารุ่นมักจะลบนามแฝง

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

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

นั่นเป็นสาเหตุที่ทำให้ Rust เกิดความปั่นป่วน เป็นภาษาทางวิศวกรรม (เทียบกับภาษาเชิงวิชาการ) ที่สนับสนุนนามแฝงและความไม่แน่นอน แต่มีการตรวจสอบคอมไพเลอร์ว่าพวกเขาจะไม่เกิดขึ้นพร้อมกัน แม้ว่าจะไม่เหมาะ แต่ก็อนุญาตให้โปรแกรมที่มีขนาดใหญ่กว่าสามารถเขียนได้อย่างปลอดภัยมากกว่ารุ่นก่อน ๆ


11

Java และ C # ให้ความปลอดภัยของหน่วยความจำโดยการตรวจสอบขอบเขตของอาเรย์และตัวชี้ dereferences

สิ่งสำคัญคือต้องคิดก่อนว่า C # และ Java ทำสิ่งนี้อย่างไร พวกเขาทำได้โดยการแปลงสิ่งที่เป็นไม่ได้กำหนดพฤติกรรมใน C หรือ C ++ ในเรื่องของพฤติกรรมที่กำหนดไว้: ความผิดพลาดของโปรแกรม ศูนย์ข้อมูลและดัชนีอาร์เรย์ไม่ควรถูกตรวจจับในโปรแกรม C # หรือ Java ที่ถูกต้อง พวกเขาไม่ควรเกิดขึ้นตั้งแต่แรกเพราะโปรแกรมไม่ควรมีข้อผิดพลาดนั้น

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

กลไกใดที่สามารถนำไปใช้กับภาษาโปรแกรมเพื่อป้องกันความเป็นไปได้ของสภาพการแข่งขันและการหยุดชะงัก

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

ดังนั้นคำถามของคุณโดยทั่วไปจะลดลงถึง "มีวิธีที่ภาษาการเขียนโปรแกรมสามารถมั่นใจได้หรือไม่ว่าโปรแกรมของฉันถูกต้อง" และคำตอบสำหรับคำถามนั้นคือในทางปฏิบัติไม่ใช่

ป่านนี้ฉันได้วิจารณ์คำถามของคุณเท่านั้น ให้ฉันลองเปลี่ยนเกียร์ที่นี่และตอบคำถามของคุณ มีตัวเลือกที่นักออกแบบภาษาสามารถทำเพื่อลดสถานการณ์ที่น่ากลัวที่เราเผชิญกับการใช้มัลติเธรดหรือไม่?

สถานการณ์เลวร้ายจริงๆ! การรับโค้ดที่มีหลายเธรดให้ถูกต้องโดยเฉพาะอย่างยิ่งในสถาปัตยกรรมโมเดลหน่วยความจำที่อ่อนแอนั้นเป็นเรื่องยากมาก เป็นคำแนะนำให้คิดว่าทำไมมันยาก:

  • การควบคุมหลายเธรดในกระบวนการเดียวนั้นยากที่จะให้เหตุผล หนึ่งเธรดนั้นยากพอ!
  • บทคัดย่อกลายเป็นสิ่งที่รั่วไหลอย่างมากในโลกที่มีหลายเธรด ในโลกของเธรดเดียวเรารับประกันว่าโปรแกรมจะทำงานเหมือนว่ามันทำงานตามลำดับแม้ว่ามันจะไม่ได้ทำงานจริงก็ตาม ในโลกที่มีหลายเธรดนั่นก็ไม่เป็นเช่นนั้นอีกต่อไป การเพิ่มประสิทธิภาพที่จะมองไม่เห็นในเธรดเดียวจะปรากฏให้เห็นและตอนนี้ผู้พัฒนาจำเป็นต้องเข้าใจการปรับให้เหมาะสมที่เป็นไปได้เหล่านั้น
  • แต่มันแย่ลงเรื่อย ๆ C # เปคกล่าวว่าการดำเนินการไม่จำเป็นต้องมีคำสั่งที่สอดคล้องกันของการอ่านและเขียนที่สามารถตกลงกันโดยหัวข้อทั้งหมด ความคิดที่ว่ามี "เผ่าพันธุ์" อยู่ตลอดและมีผู้ชนะที่ชัดเจนจริง ๆ แล้วไม่ใช่ความจริง! พิจารณาสถานการณ์ที่มีสองการเขียนและสองอ่านตัวแปรบางตัวในหลายกระทู้ ในโลกที่สมเหตุสมผลเราอาจคิดว่า "ดีเราไม่รู้ว่าใครจะชนะการแข่งขัน แต่อย่างน้อยก็จะมีการแข่งขันและใครบางคนจะชนะ" เราไม่ได้อยู่ในโลกที่สมเหตุสมผล C # อนุญาตให้หลายเธรดไม่เห็นด้วยกับการเรียงลำดับที่การอ่านและการเขียนเกิดขึ้น ไม่จำเป็นต้องมีโลกที่สอดคล้องกันซึ่งทุกคนกำลังสังเกตอยู่

ดังนั้นจึงมีวิธีที่ชัดเจนที่นักออกแบบภาษาสามารถทำให้ดีขึ้นได้ ละทิ้งชนะประสิทธิภาพการทำงานของโปรเซสเซอร์ที่ทันสมัย จัดทำโปรแกรมทั้งหมดแม้กระทั่งแบบมัลติเธรดมีโมเดลหน่วยความจำที่แข็งแกร่งมาก สิ่งนี้จะทำให้โปรแกรมหลายเธรดช้าลงหลายเท่าซึ่งทำงานโดยตรงกับเหตุผลที่มีโปรแกรมหลายเธรดในตอนแรก: เพื่อประสิทธิภาพที่ดีขึ้น

แม้จะละทิ้งโมเดลหน่วยความจำแล้วยังมีเหตุผลอื่นที่ทำให้การมัลติเธรดนั้นยาก:

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

จุดสุดท้ายนั้นมีคำอธิบายเพิ่มเติม โดย "เรียงความได้" ฉันหมายถึงสิ่งต่อไปนี้:

สมมติว่าเราต้องการคำนวณ int ที่ได้รับสองเท่า เราเขียนการดำเนินการคำนวณที่ถูกต้อง:

int F(double x) { correct implementation here }

สมมติว่าเราต้องการคำนวณสตริงที่ได้รับ int:

string G(int y) { correct implementation here }

ตอนนี้ถ้าเราต้องการคำนวณสตริงที่ได้รับสอง:

double d = whatever;
string r = G(F(d));

G และ F อาจประกอบด้วยวิธีการแก้ไขปัญหาที่ซับซ้อนมากขึ้น

แต่ล็อคไม่ได้มีคุณสมบัตินี้เพราะการหยุดชะงัก วิธีการ M1 ที่ถูกต้องที่ใช้การล็อกตามลำดับ L1, L2 และวิธีการ M2 ที่ถูกต้องที่ใช้การล็อกตามลำดับ L2, L1 ไม่สามารถใช้ทั้งสองในโปรแกรมเดียวกันได้โดยไม่ต้องสร้างโปรแกรมที่ไม่ถูกต้อง ล็อคทำขึ้นเพื่อให้คุณไม่สามารถพูดว่า "ทุกวิธีถูกต้องดังนั้นทุกอย่างถูกต้อง"

ดังนั้นเราสามารถทำอะไรได้บ้างในฐานะนักออกแบบภาษา

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

เห็นได้ชัดว่านี่ไม่ใช่การเริ่มต้น

ให้เราหันมาใส่ใจกับคำถามพื้นฐานมากขึ้น: ทำไมเราถึงมีหลายกระทู้ในตอนแรก มีสองเหตุผลหลักและพวกเขาจะพูดคุยกันในสิ่งเดียวกันบ่อยครั้งแม้ว่าพวกเขาจะแตกต่างกันมาก พวกเขาสับสนเนื่องจากทั้งคู่เกี่ยวกับการจัดการความล่าช้า

  • เราสร้างเธรดที่ไม่ถูกต้องเพื่อจัดการความหน่วงของ IO จำเป็นต้องเขียนไฟล์ขนาดใหญ่เข้าถึงฐานข้อมูลระยะไกลไม่ว่าจะสร้างเธรดผู้ปฏิบัติงานแทนที่จะล็อคเธรด UI ของคุณ

ความคิดที่ไม่ดี ใช้อะซิงโครนัสเธรดเดี่ยวแทนผ่าน coroutines แทน C # ทำสิ่งนี้ได้อย่างสวยงาม Java ไม่ค่อยดี แต่นี่เป็นวิธีหลักที่นักออกแบบภาษาปัจจุบันมีส่วนช่วยแก้ไขปัญหาการทำเกลียว ตัวawaitดำเนินการใน C # (ได้รับแรงบันดาลใจจากเวิร์กโฟลว์แบบอะซิงโครนัส F และงานศิลปะก่อนหน้าอื่น ๆ ) ได้รับการผนวกเข้ากับภาษามากขึ้นเรื่อย ๆ

  • เราสร้างเธรดอย่างถูกต้องเพื่อทำให้ซีพียูที่ไม่ทำงานทำงานอย่างหนักด้วยการทำงานหนักที่คำนวณได้ โดยทั่วไปเราใช้เธรดเป็นกระบวนการที่มีน้ำหนักเบา

นักออกแบบภาษาสามารถช่วยด้วยการสร้างคุณสมบัติภาษาที่ทำงานได้ดีกับความเท่าเทียม ลองคิดดูว่า LINQ จะขยายไปสู่ ​​PLINQ อย่างเป็นธรรมชาติได้อย่างไร หากคุณเป็นคนที่สมเหตุสมผลและคุณ จำกัด การดำเนินการ TPL ของคุณไว้ที่การทำงานของ CPU ที่ขนานกันอย่างมากและไม่แชร์หน่วยความจำคุณสามารถชนะรางวัลใหญ่ได้ที่นี่

เราทำอะไรได้อีก

  • ทำให้คอมไพเลอร์ตรวจจับข้อผิดพลาดที่มีค่ามากที่สุดและเปลี่ยนเป็นคำเตือนหรือข้อผิดพลาด

C # ไม่อนุญาตให้คุณรอในการล็อกเพราะเป็นสูตรสำหรับการหยุดชะงัก C # ไม่อนุญาตให้คุณล็อคค่าประเภทเพราะมันเป็นสิ่งที่ผิดเสมอ คุณล็อคกล่องไม่ใช่ค่า C # เตือนคุณหากคุณมีนามแฝงระเหยเพราะนามแฝงไม่ได้กำหนดความหมายได้รับ / ปล่อย มีหลายวิธีที่คอมไพเลอร์สามารถตรวจพบปัญหาที่พบบ่อยและป้องกันไม่ให้

  • ออกแบบคุณสมบัติ "คุณภาพแห่งหลุม" ซึ่งเป็นวิธีที่เป็นธรรมชาติที่สุดในการทำยังเป็นวิธีที่ถูกต้องที่สุด

C # และ Java มีข้อผิดพลาดในการออกแบบอย่างมากโดยอนุญาตให้คุณใช้วัตถุอ้างอิงใด ๆ เป็นจอภาพ สิ่งนี้กระตุ้นให้เกิดการปฏิบัติที่ไม่ดีทุกประเภทซึ่งทำให้ยากต่อการติดตามการหยุดชะงักและการป้องกันไม่ให้เกิดการหยุดนิ่ง และมันจะเสียไบต์ในทุกส่วนหัวของวัตถุ การตรวจสอบควรจะต้องได้รับจากระดับการตรวจสอบ

  • เวลาและความพยายามของ Microsoft Research จำนวนมากได้พยายามเพิ่มหน่วยความจำทรานแซคชันของซอฟต์แวร์ในภาษา C # และพวกเขาไม่เคยได้รับประสิทธิภาพที่ดีพอที่จะรวมไว้ในภาษาหลัก

STM เป็นความคิดที่สวยงามและฉันได้เล่นกับการใช้ของเล่นใน Haskell; มันช่วยให้คุณสามารถเขียนโซลูชันที่ถูกต้องได้อย่างงดงามมากขึ้นจากชิ้นส่วนที่ถูกต้องมากกว่าโซลูชันที่ใช้ระบบล็อค อย่างไรก็ตามฉันไม่ทราบรายละเอียดเพียงพอที่จะบอกว่าทำไมมันไม่สามารถทำงานได้อย่างสมบูรณ์ ถามโจดัฟฟี่ครั้งต่อไปที่คุณเห็นเขา

  • คำตอบอื่นที่กล่าวถึงการเปลี่ยนแปลงไม่ได้แล้ว หากคุณมีความผันแปรไม่ได้รวมกับ coroutines ที่มีประสิทธิภาพคุณสามารถสร้างคุณสมบัติเช่นนางแบบนักแสดงเป็นภาษาของคุณได้โดยตรง คิดว่า Erlang เช่น

มีงานวิจัยมากมายเกี่ยวกับภาษาแคลคูลัสในกระบวนการและฉันไม่เข้าใจว่าพื้นที่นั้นดีมาก ลองอ่านเอกสารสองสามฉบับด้วยตัวคุณเองและดูว่าคุณมีข้อมูลเชิงลึกหรือไม่

  • ทำให้เป็นเรื่องง่ายสำหรับบุคคลที่สามในการเขียนบทวิเคราะห์ที่ดี

หลังจากที่ฉันทำงานที่ Microsoft บน Roslyn ฉันทำงานที่ Coverity และสิ่งหนึ่งที่ฉันทำคือรับส่วนวิเคราะห์ด้านหน้าโดยใช้ Roslyn จากการมีการวิเคราะห์คำศัพท์วากยสัมพันธ์และความหมายที่จัดทำโดยไมโครซอฟท์อย่างแม่นยำเราจึงสามารถจดจ่อกับการทำงานหนักของการเขียนเครื่องตรวจจับที่พบปัญหามัลติเธรดทั่วไป

  • ยกระดับของสิ่งที่เป็นนามธรรม

เหตุผลพื้นฐานที่ว่าทำไมเรามีเผ่าพันธุ์และการหยุดชะงักและสิ่งต่าง ๆ นั้นเป็นเพราะเรากำลังเขียนโปรแกรมที่บอกว่าจะทำอะไรและมันกลับกลายเป็นว่าเราทุกคนล้วนเขียนโปรแกรมที่จำเป็น คอมพิวเตอร์ทำในสิ่งที่คุณบอกและเราบอกให้ทำสิ่งผิด ภาษาโปรแกรมสมัยใหม่จำนวนมากเกี่ยวกับการเขียนโปรแกรมเชิงประกาศมากขึ้น: พูดว่าผลลัพธ์ที่คุณต้องการและให้คอมไพเลอร์เข้าใจวิธีที่มีประสิทธิภาพปลอดภัยและถูกต้องเพื่อให้ได้ผลลัพธ์นั้น ลองนึกถึง LINQ อีกครั้ง เราต้องการให้คุณพูดfrom c in customers select c.FirstNameซึ่งเป็นการแสดงออกถึงความตั้งใจ ให้คอมไพเลอร์เข้าใจวิธีการเขียนโค้ด

  • ใช้คอมพิวเตอร์เพื่อแก้ปัญหาคอมพิวเตอร์

อัลกอริทึมการเรียนรู้ของเครื่องเป็นวิธีที่ดีกว่าในบางงานมากกว่าอัลกอริธึมที่เขียนด้วยมือถึงแม้ว่าแน่นอนว่ามีการแลกเปลี่ยนหลายอย่างรวมถึงความถูกต้องเวลาที่ใช้ในการฝึกอบรมอคติที่ได้รับการแนะนำ แต่มีความเป็นไปได้ที่งานจำนวนมากที่เรากำลังใช้รหัส "ด้วยมือ" ในไม่ช้าจะสามารถแก้ไขปัญหาที่สร้างโดยเครื่องจักรได้ หากมนุษย์ไม่ได้เขียนรหัสพวกเขาจะไม่เขียนข้อบกพร่อง

ขออภัยที่นั่นเที่ยวไปเล็กน้อย นี่เป็นหัวข้อที่ใหญ่และยากและไม่มีข้อสรุปที่ชัดเจนเกิดขึ้นในชุมชน PL ใน 20 ปีที่ฉันติดตามความคืบหน้าในพื้นที่ปัญหานี้


"โดยทั่วไปแล้วคำถามของคุณจะลดลงไปเป็น" มีวิธีที่ภาษาการเขียนโปรแกรมสามารถรับรองได้ว่าโปรแกรมของฉันถูกต้องหรือไม่ "และคำตอบสำหรับคำถามนั้นคือในทางปฏิบัติแล้วไม่มี" - จริงๆแล้วมันเป็นไปได้มาก - เรียกว่าการยืนยันอย่างเป็นทางการและในขณะที่ไม่สะดวกฉันค่อนข้างแน่ใจว่ามันทำกับซอฟต์แวร์ที่สำคัญเป็นประจำดังนั้นฉันจะไม่เรียกมันว่าใช้ไม่ได้ แต่คุณเป็นนักออกแบบภาษาคงรู้เรื่องนี้อยู่แล้ว ...
mrpyo

6
@mrpyo: ฉันรู้ดี มีปัญหามากมาย ครั้งแรก: ฉันเคยเข้าร่วมการประชุมการตรวจสอบอย่างเป็นทางการโดยทีมวิจัย MSFT นำเสนอผลลัพธ์ใหม่ที่น่าตื่นเต้นพวกเขาสามารถขยายเทคนิคของพวกเขาเพื่อตรวจสอบโปรแกรมแบบมัลติเธรดที่มีความยาวได้ถึงยี่สิบบรรทัดและมีตัวตรวจสอบการทำงาน นี่เป็นการนำเสนอที่น่าสนใจ แต่ไม่มีประโยชน์สำหรับฉัน ฉันมีโปรแกรม 20 ล้านบรรทัดเพื่อวิเคราะห์
Eric Lippert

@mrpyo: ที่สองที่ฉันกล่าวถึงปัญหาใหญ่กับล็อคคือโปรแกรมที่ทำจากวิธีการที่ปลอดภัย thread ไม่จำเป็นต้องเป็นโปรแกรมที่ปลอดภัยด้าย การตรวจสอบวิธีการของแต่ละบุคคลอย่างเป็นทางการนั้นไม่ได้ช่วย แต่อย่างใดและการวิเคราะห์โปรแกรมทั้งหมดนั้นทำได้ยากสำหรับโปรแกรมที่ไม่สำคัญ
Eric Lippert

6
@mrpyo: ประการที่สามปัญหาใหญ่ที่มีการวิเคราะห์อย่างเป็นทางการก็คือเรากำลังทำอะไรอยู่ เรากำลังนำเสนอสเปคของเงื่อนไขเบื้องต้นและ postconditionsแล้วตรวจสอบว่าโปรแกรมตรงตามข้อกำหนด ที่ดี; ในทางทฤษฎีที่ทำได้โดยสิ้นเชิง สเปคเขียนเป็นภาษาอะไร? หากมีภาษาสเปคที่ชัดเจนตรวจสอบได้ให้ลองเขียนโปรแกรมทั้งหมดของเราในภาษานั้นและรวบรวมสิ่งนั้น ทำไมเราไม่ทำเช่นนี้? เพราะปรากฎว่ามันยากที่จะเขียนโปรแกรมที่ถูกต้องในภาษาสเปคด้วย!
Eric Lippert

2
การวิเคราะห์แอปพลิเคชันเพื่อความถูกต้องโดยใช้เงื่อนไขล่วงหน้า / หลังเงื่อนไขเป็นไปได้ (เช่นการใช้สัญญาการเข้ารหัส) อย่างไรก็ตามการวิเคราะห์ดังกล่าวมีความเป็นไปได้เฉพาะในเงื่อนไขที่ว่าเงื่อนไขนั้นเป็นองค์ประกอบซึ่งไม่สามารถล็อคได้ ฉันจะทราบด้วยว่าการเขียนโปรแกรมในลักษณะที่ช่วยให้การวิเคราะห์นั้นต้องมีวินัยอย่างระมัดระวัง ตัวอย่างเช่นแอปพลิเคชันที่ล้มเหลวในการปฏิบัติตามหลักการทดแทน Liskov อย่างเคร่งครัดมีแนวโน้มที่จะต่อต้านการวิเคราะห์
Brian
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.