การทำงานพร้อมกัน: คุณเข้าใกล้การออกแบบและดีบักการใช้งานได้อย่างไร


37

ฉันได้พัฒนาระบบที่เกิดขึ้นพร้อมกันมาหลายปีแล้วและฉันก็เข้าใจดีในเรื่องนี้แม้จะขาดการฝึกอบรมอย่างเป็นทางการ (เช่นไม่มีระดับ) มีภาษาใหม่ไม่กี่ภาษาที่ได้รับความนิยมอย่างน้อยพูดถึงเมื่อเร็ว ๆ นี้ซึ่งได้รับการออกแบบมาเพื่อทำให้การทำงานพร้อมกันง่ายขึ้นเช่น Erlang และ Go ดูเหมือนว่าวิธีการของพวกเขาในการทำงานพร้อมกันนั้นสะท้อนถึงประสบการณ์ของฉันเองว่าจะทำให้ระบบปรับขนาดได้และใช้ประโยชน์จากหลายคอร์ / โปรเซสเซอร์ / เครื่อง

อย่างไรก็ตามฉันพบว่ามีเครื่องมือน้อยมากที่จะช่วยให้เห็นภาพสิ่งที่คุณตั้งใจจะทำและยืนยันว่าอย่างน้อยคุณก็ใกล้เคียงกับวิสัยทัศน์ดั้งเดิมของคุณ การดีบักโค้ดที่เกิดขึ้นพร้อมกันอาจเป็นฝันร้ายที่มีภาษาที่ไม่ได้ออกแบบมาสำหรับการทำงานพร้อมกัน (เช่น C / C ++, C #, Java, ฯลฯ ) โดยเฉพาะอย่างยิ่งมันเป็นไปไม่ได้ที่จะสร้างเงื่อนไขที่เกิดขึ้นใหม่ในระบบเดียวในสภาพแวดล้อมการพัฒนาของคุณ

ดังนั้นอะไรคือแนวทางของคุณในการออกแบบระบบเพื่อจัดการกับการทำงานพร้อมกันและการประมวลผลแบบขนาน? ตัวอย่าง:

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

ฉันมีคำตอบของตัวเองสำหรับสิ่งเหล่านี้ แต่ฉันก็ต้องการที่จะเรียนรู้เพิ่มเติมอีกเล็กน้อย

แก้ไข

จนถึงตอนนี้เรามีข้อมูลที่ดีมากมาย บทความหลายบทความที่เชื่อมโยงนั้นดีมากและฉันได้อ่านมาแล้วบางส่วน

ประสบการณ์ส่วนตัวของฉันกับการเขียนโปรแกรมพร้อมกันทำให้ฉันเชื่อว่าคุณต้องการความคิดที่แตกต่างจากการเขียนโปรแกรมตามลำดับ ความแตกแยกทางจิตใจนั้นกว้างพอ ๆ กับความแตกต่างระหว่างการเขียนโปรแกรมเชิงวัตถุและการโปรแกรมเชิงกระบวนวิธี ฉันต้องการชุดคำถามนี้เพื่อมุ่งเน้นที่กระบวนการคิดที่จำเป็น (เช่นทฤษฎี) เพื่อเข้าหาคำตอบอย่างเป็นระบบ เมื่อให้คำตอบที่เป็นรูปธรรมมากขึ้นมันจะช่วยยกตัวอย่าง - สิ่งที่คุณต้องผ่านเป็นการส่วนตัว

เป้าหมายสำหรับค่าหัว

อย่าบอกฉันว่าฉันควรทำอย่างไร ฉันมีสิ่งนั้นอยู่ภายใต้การควบคุม บอกฉันว่าคุณทำอะไร บอกฉันทีว่าคุณแก้ปัญหาเหล่านี้อย่างไร


นี่เป็นคำถามที่ดี - มีความลึกมาก ฉันยังได้รับประสบการณ์ที่ดีกับแอพพลิเคชั่นแบบมัลติเธรดใน Java แต่ต้องการเรียนรู้เพิ่มเติม
Michael K

จนถึงตอนนี้เรามีคำตอบที่ดี ใครต้องการที่จะเสี่ยงแทงในสิ่งที่คุณต้องการคุณจะต้องช่วยคุณในเรื่องนี้?
Berin Loritsch

TotalView Debugger สำหรับการเขียนโค้ดพร้อมกันเป็นเครื่องมือที่มีประโยชน์มากใช้เวลาเรียนรู้บ้างเล็กน้อย - totalviewtech.com/products/totalview.html
Fanatic23

บางทีการบันทึกอาจช่วยคุณได้ด้วยคำถามสองข้อสุดท้าย
Amir Rezaei

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

คำตอบ:


11

ฉันได้พัฒนาระบบที่เกิดขึ้นพร้อมกันมาหลายปีแล้วและฉันก็เข้าใจดีในเรื่องนี้แม้จะขาดการฝึกอบรมอย่างเป็นทางการ (เช่นไม่มีระดับ)

โปรแกรมเมอร์ที่ดีที่สุดหลายคนที่ฉันรู้จักไม่จบมหาวิทยาลัย สำหรับฉันฉันเรียนปรัชญา

C / C ++, C #, Java, ฯลฯ ) โดยเฉพาะอย่างยิ่งมันเป็นไปไม่ได้ที่จะสร้างเงื่อนไขที่เกิดขึ้นใหม่ในระบบเดียวในสภาพแวดล้อมการพัฒนาของคุณ

ใช่

คุณคิดได้อย่างไรว่าอะไรจะเกิดขึ้นพร้อมกันกับสิ่งที่ต้องเรียงตามลำดับ?

เรามักจะเริ่มต้นด้วยคำอุปมาสูง 1,000 ไมล์เพื่ออธิบายสถาปัตยกรรมของเรากับตัวเรา (ตอนแรก) และเพื่อคนอื่น ๆ (ที่สอง)

เมื่อเราเผชิญกับปัญหานั้นเรามักพบวิธีที่จะ จำกัด การมองเห็นของวัตถุที่เกิดขึ้นพร้อมกันกับสิ่งที่ไม่เกิดขึ้นพร้อมกัน

เมื่อเร็ว ๆ นี้ฉันค้นพบนักแสดงในสกาล่าและฉันเห็นว่าวิธีแก้ปัญหาแบบเก่าของฉันนั้นเป็น "miniactors" ซึ่งมีพลังน้อยกว่าสกาล่า ดังนั้นข้อเสนอแนะของฉันคือการเริ่มต้นจากที่นั่น

ข้อเสนอแนะอีกประการหนึ่งคือการข้ามปัญหาให้มากที่สุดตัวอย่างเช่นเราใช้ centralized cache (terracotta) แทนการเก็บแผนที่ไว้ในหน่วยความจำโดยใช้ callback ระดับชั้นในแทนวิธีการซิงโครไนซ์ส่งข้อความแทนการเขียนหน่วยความจำที่ใช้ร่วมกันเป็นต้น

ด้วยสกาล่ามันง่ายกว่ามากอยู่แล้ว

คุณจะสร้างเงื่อนไขข้อผิดพลาดและดูว่าเกิดอะไรขึ้นเมื่อแอปพลิเคชันดำเนินการอย่างไร

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

คุณเห็นภาพปฏิสัมพันธ์ระหว่างส่วนต่าง ๆ ที่เกิดขึ้นพร้อมกันของแอปพลิเคชันอย่างไร

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

สำหรับ Arch ที่นี่ฉันหมายถึงคำจำกัดความของ Neal Ford: Sw Architecture คือทุกสิ่งที่ยากที่จะเปลี่ยนแปลงในภายหลัง

การเขียนโปรแกรมทำให้ฉันเชื่อว่าคุณต้องการความคิดที่แตกต่างจากการเขียนโปรแกรมตามลำดับ

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


6

สำหรับฉันนั้นเกี่ยวกับข้อมูลทั้งหมด ทำลายข้อมูลของคุณและการประมวลผลแบบขนานนั้นง่าย ปัญหาทั้งหมดเกี่ยวกับการเก็บรักษาการหยุดชะงักและอื่น ๆ หายไป

ฉันรู้ว่านี่ไม่ใช่วิธีเดียวในการขนาน แต่สำหรับฉันนั้นมีประโยชน์มากที่สุด

เพื่อแสดงให้เห็นถึงเรื่องราว (ไม่ดัง)

ฉันทำงานเกี่ยวกับระบบการเงิน (การควบคุมตลาดหุ้น) ขนาดใหญ่ในปี 2007 ถึง 2009 และปริมาณการประมวลผลของข้อมูลมีขนาดใหญ่มาก เพื่อแสดงการคำนวณทั้งหมดที่ทำกับ 1 บัญชีเดียวของลูกค้าใช้เวลาประมาณ 1 ~ 3 วินาทีในเวิร์กสเตชันเฉลี่ยของพวกเขาและมีบัญชีมากกว่า 30k บัญชี ทุกคืนการปิดระบบเป็นปัญหาใหญ่สำหรับผู้ใช้ (โดยปกติแล้วจะใช้เวลาประมวลผลมากกว่า 6 ชั่วโมงโดยไม่มีข้อผิดพลาดใด ๆ สำหรับพวกเขา)

การศึกษาปัญหาเพิ่มเติมเผยว่าเราสามารถแยกการคำนวณระหว่างคอมพิวเตอร์หลาย ๆ เครื่อง แต่เรายังคงมีคอขวดขนาดใหญ่บนเซิร์ฟเวอร์ฐานข้อมูลเก่า (เซิร์ฟเวอร์ SQL 2000 จำลอง SQL 6.5)

มันค่อนข้างชัดเจนว่าแพ็คเก็ตการประมวลผลขั้นต่ำของเราคือการคำนวณบัญชีเดียวและคอขวดที่สำคัญคือการเก็บรักษาเซิร์ฟเวอร์ฐานข้อมูล (เราสามารถเห็นการเชื่อมต่อหลาย ๆ ดังนั้นกระบวนการแบบขนานจึงเป็นดังนี้:

1) ผู้ผลิตรายเดียวมีหน้าที่รับผิดชอบในการอ่านฐานข้อมูลหรือเขียนตามลำดับ ไม่อนุญาตให้ใช้งานพร้อมกันที่นี่ ผู้ผลิตเตรียมงานสำหรับผู้บริโภค ฐานข้อมูลเป็นของผู้ผลิตนี้เท่านั้น

2) ผู้บริโภคหลายคนบนเครื่องหลายเครื่อง ผู้บริโภคแต่ละรายได้รับข้อมูลทั้งหมดจากคิวพร้อมที่จะคำนวณ การดำเนินการ deqeue แต่ละครั้งจะทำข้อมูลให้ตรงกัน

3) หลังจากการคำนวณผู้ใช้บริการแต่ละรายจะส่งข้อมูลกลับไปยังคิวที่อยู่ในหน่วยความจำที่ซิงโครไนซ์ให้กับผู้ผลิตเพื่อคงข้อมูลไว้

มีหลายจุดตรวจสอบกลไกต่าง ๆ เพื่อให้มั่นใจว่าธุรกรรมถูกบันทึกอย่างถูกต้อง (ไม่มีใครถูกทิ้งไว้ข้างหลัง) แต่งานทั้งหมดมีค่า ในท้ายที่สุดการคำนวณจะแพร่กระจายไปยังคอมพิวเตอร์ 10 เครื่อง (รวมถึงผู้ผลิต / คิวคอมพิวเตอร์) ซึ่งทำให้ระบบปิดทั้งระบบเป็น 15 นาที

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


2

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

ให้ฉันลองตอบคำถามของคุณทีละคน

* How do you figure out what can be made concurrent vs. what has to be sequential?

ใช้พร้อมกันสำหรับ

1) การสำรวจ: - ต้องการเธรดเพื่อสำรวจความคิดเห็นอย่างต่อเนื่องหรือส่งการอัปเดตเป็นประจำ (แนวคิดเช่น heart-bits ซึ่งส่งข้อมูลบางอย่างในช่วงเวลาปกติไปยังเซิร์ฟเวอร์กลางเพื่อบอกว่าฉันยังมีชีวิตอยู่)

2) การดำเนินการที่มี i / o หนักสามารถทำแบบขนาน ตัวอย่างที่ดีที่สุดคือคนตัดไม้ เธรดตัวบันทึกอาจเป็นเธรดแยกต่างหาก

3) งานที่คล้ายกันในข้อมูลที่แตกต่างกัน หากมีงานบางอย่างที่เกิดขึ้นกับข้อมูลที่แตกต่างกัน แต่มีลักษณะคล้ายกันมากเธรดที่ต่างกันสามารถทำได้ ตัวอย่างที่ดีที่สุดคือคำขอของเซิร์ฟเวอร์

และนอกหลักสูตรอื่น ๆ อีกมากมายเช่นนี้ขึ้นอยู่กับแอปพลิเคชัน

* How do you reproduce error conditions and view what is happening as the application executes?

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

* How do you visualize the interactions between the different concurrent parts of the application?

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

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


2
  • คุณคิดได้อย่างไรว่าอะไรจะเกิดขึ้นพร้อมกันกับสิ่งที่ต้องเรียงตามลำดับ?

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

การทำงานกับ Erlang ฉันรักแนวคิดการใช้การส่งข้อความแบบอะซิงโครนัสและนางแบบนักแสดงพร้อมกัน - มันใช้งานง่ายมีประสิทธิภาพและสะอาดตา

ออกจากการทำความเข้าใจพร้อมกันของนักแสดง

โมเดลนักแสดงประกอบด้วยหลักการสำคัญสองสามข้อ:

  • ไม่มีสถานะที่แบ่งปัน
  • กระบวนการที่มีน้ำหนักเบา
  • การส่งข้อความแบบอะซิงโครนัส
  • กล่องจดหมายเพื่อบัฟเฟอร์ข้อความขาเข้า
  • การประมวลผลกล่องจดหมายด้วยการจับคู่รูปแบบ

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

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

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

รุ่นนี้ไม่ได้เป็น Erlang เอกสิทธิ์แม้ในโลก Java และ. NET มีวิธีการสร้างนี้ - ฉันจะดูConcurrencyและCo ประสาน Runtime (CCR)และRelang (ยังมี Jetlang สำหรับ Java)

  • คุณจะสร้างเงื่อนไขข้อผิดพลาดและดูว่าเกิดอะไรขึ้นเมื่อแอปพลิเคชันดำเนินการอย่างไร

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

  • คุณเห็นภาพปฏิสัมพันธ์ระหว่างส่วนต่าง ๆ ที่เกิดขึ้นพร้อมกันของแอปพลิเคชันอย่างไร

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


1

- คำตอบของฉันคือ MS / Visual Studio โดยเฉพาะ -

คุณคิดได้อย่างไรว่าอะไรจะเกิดขึ้นพร้อมกันกับสิ่งที่ต้องเรียงตามลำดับ?

นั่นจะนำความรู้เกี่ยวกับโดเมนไม่มีคำสั่งแบบครอบคลุมใด ๆ ที่นี่เพื่อครอบคลุม

คุณจะสร้างเงื่อนไขข้อผิดพลาดและดูว่าเกิดอะไรขึ้นเมื่อแอปพลิเคชันดำเนินการอย่างไร

มีการบันทึกจำนวนมากความสามารถในการเปิด / ปิด / ปิดการบันทึกในแอปพลิเคชันการผลิตเพื่อที่จะจับมันในการผลิต VS2010 Intellitraceน่าจะช่วยได้ แต่ฉันยังไม่ได้ใช้

คุณเห็นภาพปฏิสัมพันธ์ระหว่างส่วนต่าง ๆ ที่เกิดขึ้นพร้อมกันของแอปพลิเคชันอย่างไร

ฉันไม่มีคำตอบที่ดีสำหรับเรื่องนี้ชอบที่จะเห็น


การบันทึกจะเปลี่ยนวิธีการเรียกใช้โค้ดและอาจทำให้เกิดข้อผิดพลาดที่คุณไม่ได้ปรากฏขึ้น
Matthew อ่าน

1

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

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

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

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

จากนั้นอีกครั้งโยน 'กระจาย' ในนั้นและอนุญาโตตุลาการจะต้อง คุณมีตัวอย่างเฉพาะหรือไม่


เพื่อชี้แจงคำสั่งของฉัน C ไม่ได้ถูกออกแบบมาโดยเฉพาะสำหรับและรอบ ๆ การทำงานพร้อมกัน สิ่งนี้ตรงกันข้ามกับภาษาอย่าง Go, Erlang และ Scala ซึ่งได้รับการออกแบบอย่างชัดเจนโดยคำนึงถึงภาวะพร้อมกัน ฉันไม่ได้ตั้งใจจะบอกว่าคุณไม่สามารถทำงานพร้อมกันกับ C.
Berin Loritsch

1

คุณจะสร้างเงื่อนไขข้อผิดพลาดและดูว่าเกิดอะไรขึ้นเมื่อแอปพลิเคชันดำเนินการอย่างไร

คุณเห็นภาพปฏิสัมพันธ์ระหว่างส่วนต่าง ๆ ที่เกิดขึ้นพร้อมกันของแอปพลิเคชันอย่างไร

จากประสบการณ์ของฉันคำตอบของทั้งสองด้านมีดังนี้:

การติดตามแบบกระจาย

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

การติดตามแบบกระจายมีต้นกำเนิดในระบบแบบกระจาย (แน่นอน) ซึ่งนิยามแบบอะซิงโครนัสและพร้อมกันสูง ระบบกระจายที่มีการติดตามแบบกระจายช่วยให้ผู้คนสามารถ:

a) ระบุปัญหาคอขวดที่สำคัญ b) รับการแสดงภาพของ 'แอพพลิเคชั่น' ในอุดมคติของแอพพลิเคชั่นของคุณและ c) แสดงทัศนวิสัยว่าพฤติกรรมใดที่เกิดขึ้นพร้อมกัน d) รับข้อมูลจังหวะเวลา ระบบ (สำคัญมากหากคุณมี SLA ที่แข็งแกร่ง)

อย่างไรก็ตามผลลัพธ์ของการติดตามแบบกระจายคือ:

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

  2. มีเครื่องมือต่าง ๆ มากมายซึ่งไม่สามารถใช้งานร่วมกันได้ทั้งหมด สิ่งนี้ค่อนข้างได้รับการแก้ไขตามมาตรฐานเช่น OpenTracing แต่ไม่สามารถแก้ไขได้ทั้งหมด

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

  4. เครื่องมือปัจจุบันถือว่าคุณมีหน่วยความจำและที่เก็บข้อมูลสำรอง การโฮสต์เซิร์ฟเวอร์ Timeseries อาจไม่ถูกขึ้นอยู่กับข้อ จำกัด ของคุณ

ซอฟต์แวร์ติดตามข้อผิดพลาด

ฉันเชื่อมโยงไปยัง Sentry ข้างต้นเป็นหลักเพราะเป็นเครื่องมือที่ใช้กันอย่างแพร่หลายและด้วยเหตุผลที่ดี - ซอฟต์แวร์การติดตามข้อผิดพลาดเช่นการดำเนินการ Sentry hijack runtime เพื่อส่งต่อสแต็กติดตามของข้อผิดพลาดที่พบกับเซิร์ฟเวอร์กลาง

ประโยชน์สุทธิของซอฟต์แวร์เฉพาะดังกล่าวในรหัสที่เกิดขึ้นพร้อมกัน:

  1. ข้อผิดพลาดที่ซ้ำกันจะไม่ซ้ำกัน กล่าวอีกนัยหนึ่งถ้าหนึ่งหรือมากกว่าหนึ่งระบบพร้อมกันพบข้อยกเว้นเดียวกันยามจะเพิ่มรายงานเหตุการณ์ที่เกิดขึ้น แต่ไม่ส่งสองชุดของเหตุการณ์

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

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

  1. คุณสามารถแก้ไขซอฟต์แวร์จัดการข้อผิดพลาดนี้เพื่อให้รายละเอียดเพิ่มเติมพร้อมกับข้อยกเว้นรันไทม์ของคุณ กระบวนการเปิดแหล่งข้อมูลใดบ้าง มีทรัพยากรที่ใช้ร่วมกันที่กระบวนการนี้ถืออยู่หรือไม่ ผู้ใช้รายใดประสบปัญหานี้

นอกเหนือจากการติดตามสแต็กอย่างพิถีพิถัน (และแมปแหล่งที่มาหากคุณต้องจัดเตรียมเวอร์ชันไฟล์ย่อของคุณ) ทำให้ง่ายต่อการพิจารณาว่าเกิดอะไรขึ้นเป็นส่วนใหญ่

  1. (ระบุเฉพาะยาม) คุณสามารถมีแดชบอร์ดการรายงาน Sentry แยกต่างหากสำหรับการทดสอบการทำงานของระบบช่วยให้คุณสามารถตรวจจับข้อผิดพลาดในการทดสอบ

ข้อเสียของซอฟต์แวร์ดังกล่าว ได้แก่ :

  1. ชอบทุกอย่างพวกเขาเพิ่มจำนวนมาก คุณอาจไม่ต้องการระบบดังกล่าวบนฮาร์ดแวร์ฝังตัวเป็นต้น ฉันขอแนะนำให้ทำการทดลองใช้งานซอฟต์แวร์ดังกล่าวโดยเปรียบเทียบกับการดำเนินการอย่างง่าย ๆ ที่มีและไม่มีการสุ่มตัวอย่างมากกว่าสองร้อยรันบนเครื่องที่ไม่ได้ใช้งาน

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

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

  4. พวกเขาอาจไม่ให้ข้อมูลที่คุณต้องการเสมอไป นี่เป็นความเสี่ยงเมื่อพยายามเพิ่มการมองเห็น

  5. บริการเหล่านี้ส่วนใหญ่ได้รับการออกแบบสำหรับเว็บแอพพลิเคชั่นพร้อมกันสูงดังนั้นเครื่องมือบางอย่างอาจไม่สมบูรณ์แบบสำหรับกรณีการใช้งานของคุณ

กล่าวโดยสรุป : การมีทัศนวิสัยเป็นส่วนที่สำคัญที่สุดของระบบใด ๆ ที่เกิดขึ้นพร้อมกัน สองวิธีที่ฉันอธิบายข้างต้นร่วมกับแดชบอร์ดเฉพาะเกี่ยวกับฮาร์ดแวร์และข้อมูลเพื่อให้ได้ภาพ holidtic ของระบบในเวลาใดก็ตามที่ใช้กันอย่างแพร่หลายในอุตสาหกรรมอย่างแม่นยำเพื่อที่อยู่ด้านนั้น

คำแนะนำเพิ่มเติมบางส่วน

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

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

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

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

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

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

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

กฎทั่วไปของหัวแม่มือ: การออกแบบสำหรับความล้มเหลวในระบบพร้อมกัน คาดว่าบริการทั่วไปจะพังหรือเสียหาย สิ่งนี้จะเป็นไปได้แม้กระทั่งรหัสที่ไม่ได้กระจายข้ามเครื่อง - รหัสที่เกิดขึ้นพร้อมกันในเครื่องเดียวสามารถพึ่งพาการพึ่งพาจากภายนอก (เช่นไฟล์บันทึกที่ใช้ร่วมกันเซิร์ฟเวอร์ Redis เซิร์ฟเวอร์ MySQL แช่ง) ที่อาจหายไปหรือถูกลบออกได้ตลอดเวลา .

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

คุณคิดออกว่าสามารถทำอะไรพร้อมกันและสิ่งที่สามารถทำตามลำดับ?

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

หากไม่มีการวัดคุณจะไม่สามารถทำสิ่งสำคัญสองสามประการ:

  1. ประเมินความแตกต่างที่เกิดจากการเปลี่ยนแปลงระบบ หากคุณไม่ทราบว่าปุ่มปรับแต่ง A ที่ทำขึ้น B ตัวชี้วัดขึ้นและตัวชี้วัด C ลงไปคุณไม่ทราบวิธีการแก้ไขระบบของคุณเมื่อมีคนกดรหัสร้ายในระบบของคุณ (และพวกเขาจะผลักดันรหัสไปยังระบบของคุณ) .

  2. ทำความเข้าใจกับสิ่งที่คุณต้องทำต่อไปเพื่อปรับปรุงสิ่งต่าง ๆ จนกว่าคุณจะรู้ว่าแอปพลิเคชั่นมีหน่วยความจำเหลือน้อยคุณจะไม่สามารถแยกแยะว่าคุณควรได้รับหน่วยความจำเพิ่มหรือซื้อดิสก์เพิ่มสำหรับเซิร์ฟเวอร์ของคุณ

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

ที่ถูกกล่าวว่ามีกฎง่ายๆไม่กี่:

  1. ลำดับหมายถึงการพึ่งพา กระบวนการสองกระบวนการควรเรียงตามลำดับหากกระบวนการหนึ่งขึ้นอยู่กับอีกกระบวนการหนึ่ง กระบวนการที่ไม่มีการขึ้นต่อกันควรจะเกิดขึ้นพร้อมกัน อย่างไรก็ตามวางแผนวิธีจัดการกับความล้มเหลวของสตรีมที่ไม่ได้ป้องกันกระบวนการดาวน์สตรีมจากการรออย่างไม่มีกำหนด

  2. อย่าผสมภารกิจที่ผูกมัด I / O กับงานที่ผูกกับ CPU บนแกนหลักเดียวกัน อย่า (ตัวอย่าง) เขียนโปรแกรมรวบรวมข้อมูลเว็บที่เปิดใช้งานคำขอที่เกิดขึ้นพร้อมกันสิบรายการในเธรดเดียวกัน scones พวกเขาทันทีที่พวกเขาเข้ามาและคาดว่าจะเพิ่มเป็นห้าร้อย - คำขอ I / O ไปที่คิวพร้อมกัน แต่ CPU จะยังคงดำเนินต่อไปตามลำดับ (โมเดลเหตุการณ์ที่ขับเคลื่อนด้วยเธรดเดี่ยวนี้เป็นโมเดลที่ได้รับความนิยม แต่มีข้อ จำกัด เนื่องจากด้านนี้ - แทนที่จะเข้าใจสิ่งนี้ผู้คนเพียงแค่บีบมือแล้วบอกว่าโหนดไม่ได้ปรับขนาดเพื่อเป็นตัวอย่างให้กับคุณ)

เธรดเดียวสามารถทำงาน I / O ได้มาก แต่เพื่อที่จะใช้งานพร้อมกันอย่างเต็มที่ของฮาร์ดแวร์ของคุณใช้ threadpools ที่ร่วมกันครอบครองแกนทั้งหมด ในตัวอย่างข้างต้นการเปิดตัวกระบวนการ Python ห้ากระบวนการ (ซึ่งแต่ละกระบวนการสามารถใช้คอร์ในเครื่องหกคอร์) สำหรับการทำงานของ CPU และเธรด Python ที่หกสำหรับการทำงานของ I / O จะเร็วขึ้นกว่าที่คุณคิด

วิธีเดียวที่จะใช้ประโยชน์จากการทำงานพร้อมกันของ CPU คือการใช้เธรดพูล เธรดเดี่ยวมักจะดีพอสำหรับงาน I / O ที่ถูกผูกไว้จำนวนมาก นี่คือเหตุผลว่าทำไมเว็บเซิร์ฟเวอร์ที่ขับเคลื่อนด้วยเหตุการณ์เช่น Nginx ปรับขนาดได้ดีกว่า (พวกเขาทำงานที่ถูกผูกไว้กับ I / O อย่างแท้จริง) กว่า Apache (ซึ่งทำให้ I / O ถูกผูกไว้ทำงานกับสิ่งที่ต้องการ CPU และเปิดตัวกระบวนการต่อคำขอ) การคำนวณ GPU นับหมื่นที่ได้รับในแบบคู่ขนานเป็นความคิดที่แย่มาก


0

ดีสำหรับขั้นตอนการยืนยันเมื่อออกแบบระบบพร้อมกันมีขนาดใหญ่ - ฉันมักจะทดสอบรูปแบบการใช้LTSA - ป้ายวิเคราะห์ระบบการเปลี่ยน มันได้รับการพัฒนาโดยครูสอนพิเศษคนเก่าของฉันซึ่งเป็นทหารผ่านศึกในสาขาการทำงานพร้อมกันและเป็นหัวหน้าฝ่ายคอมพิวเตอร์ที่ Imperial ตอนนี้

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


0

คุณคิดได้อย่างไรว่าอะไรจะเกิดขึ้นพร้อมกันกับสิ่งที่ต้องเรียงตามลำดับ?

ค่อนข้างทุกสิ่งที่คุณเขียนสามารถใช้ประโยชน์จากการเกิดพร้อมกันโดยเฉพาะอย่างยิ่งกรณีการใช้ "devide an conquer" คำถามที่ดีกว่าคือสิ่งที่ควรจะเกิดขึ้นพร้อมกัน?

การทำเกลียวของ Joseph Albahari ในรายการC #ห้าการใช้งานทั่วไป

มัลติเธรดมีประโยชน์หลายอย่าง นี่เป็นเรื่องธรรมดาที่สุด:

การรักษาส่วนต่อประสานผู้ใช้ที่ตอบสนองได้

ด้วยการเรียกใช้งานที่ต้องใช้เวลามากในเธรด“ ผู้ปฏิบัติงาน” แบบขนานเธรด UI หลักจะสามารถดำเนินการกับเหตุการณ์แป้นพิมพ์และเมาส์ต่อไปได้

การใช้ CPU ที่ถูกบล็อกอย่างมีประสิทธิภาพ

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

การเขียนโปรแกรมแบบขนาน

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

การดำเนินการเก็งกำไร

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

การอนุญาตให้ประมวลผลคำขอพร้อมกัน

บนเซิร์ฟเวอร์คำขอไคลเอนต์สามารถมาพร้อมกันดังนั้นจำเป็นต้องจัดการแบบขนาน (. NET Framework สร้างเธรดสำหรับสิ่งนี้โดยอัตโนมัติถ้าคุณใช้ ASP.NET, WCF, Web Services หรือ Remoting) สิ่งนี้ยังมีประโยชน์ในไคลเอนต์ (เช่นการจัดการเครือข่ายแบบเพียร์ทูเพียร์หรือแม้แต่คำขอจำนวนมากจากผู้ใช้)

หากคุณไม่ได้พยายามทำตามข้อใดข้อหนึ่งข้างต้นคุณควรคิดให้ดีกว่านี้

คุณจะสร้างเงื่อนไขข้อผิดพลาดและดูว่าเกิดอะไรขึ้นเมื่อแอปพลิเคชันดำเนินการอย่างไร

หากคุณใช้. NET และคุณได้เขียนกรณีการใช้งานคุณสามารถใช้CHESSซึ่งสามารถสร้างเงื่อนไขการสอดแทรกเธรดเฉพาะใหม่ซึ่งช่วยให้คุณสามารถทดสอบการแก้ไขของคุณ

คุณเห็นภาพปฏิสัมพันธ์ระหว่างส่วนต่าง ๆ ที่เกิดขึ้นพร้อมกันของแอปพลิเคชันอย่างไร

มันขึ้นอยู่กับบริบท สำหรับสถานการณ์ของผู้ปฏิบัติงานฉันคิดว่าผู้จัดการเป็นรอง ผู้จัดการแจ้งให้ผู้ใต้บังคับบัญชาทำบางสิ่งบางอย่างและรอการอัพเดทสถานะ

สำหรับงานที่ไม่เกี่ยวข้องพร้อมกันฉันคิดว่าลิฟท์หรือรถยนต์แยกเลนกัน

สำหรับการซิงโครไนซ์บางครั้งฉันนึกถึงสัญญาณไฟจราจรหรือเลี้ยว

นอกจากนี้หากคุณใช้ C # 4.0 คุณอาจต้องการดูที่Task Parallel Library


0

คำตอบของฉันสำหรับคำถามนี้คือ:

  • คุณคิดได้อย่างไรว่าอะไรจะเกิดขึ้นพร้อมกันกับสิ่งที่ต้องเรียงตามลำดับ?

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

หากคุณต้องจำลองสถานการณ์ในชีวิตจริงเช่นคิวเวิร์กโฟลว์ ฯลฯ คุณอาจต้องใช้วิธีการทำงานพร้อมกัน

ตอนนี้ฉันรู้แล้วว่าฉันควรใช้มันถึงเวลาแล้วที่จะวิเคราะห์การแลกเปลี่ยนหากคุณมีความสำเร็จมากมายคุณอาจคิดเกี่ยวกับการสื่อสารด้านบน แต่ถ้าคุณต้องใหม่อาจจบลงด้วยการแก้ปัญหาไม่พร้อมกัน (reanalize ปัญหาถ้า ดังนั้น.)

  • คุณจะสร้างเงื่อนไขข้อผิดพลาดและดูว่าเกิดอะไรขึ้นเมื่อแอปพลิเคชันดำเนินการอย่างไร

ฉันไม่มีความเชี่ยวชาญในเรื่องนี้ แต่ฉันคิดว่าสำหรับระบบที่ทำงานพร้อมกันนี่ไม่ใช่วิธีที่ถูกต้อง ควรเลือกวิธีการทางทฤษฎีโดยมองหาความต้องการการหยุดชะงักทั้ง 4 ข้อในพื้นที่สำคัญ:

  1. ไม่ใช่ความจองหอง
  2. รอสักครู่
  3. การยกเว้นแรงจูงใจ
  4. โซ่แบบวงกลม

    • คุณเห็นภาพปฏิสัมพันธ์ระหว่างส่วนต่าง ๆ ที่เกิดขึ้นพร้อมกันของแอปพลิเคชันอย่างไร

ฉันพยายามระบุว่าใครคือผู้เข้าร่วมในการโต้ตอบก่อนจากนั้นพวกเขาจะสื่อสารกันอย่างไรและกับใคร ในที่สุดกราฟและไดอะแกรมการโต้ตอบช่วยให้ฉันเห็นภาพ ไวท์บอร์ดเก่าที่ดีของฉันไม่สามารถถูกสื่ออื่น ๆ


0

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

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

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

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

ในที่สุดเครื่องมือ การดีบักนั้นยากมาก ฉันใช้ valgrind \ callgrind บน linux ร่วมกับ PIN และสตูดิโอแบบขนานบน windows อย่าพยายามและแก้ไขข้อบกพร่องด้วยตนเอง คุณอาจจะสามารถ แต่คุณอาจหวังว่าคุณจะไม่ได้ สิบชั่วโมงเชี่ยวชาญเครื่องมือที่ทรงพลังและแบบจำลองที่ดีบางอย่างจะช่วยให้คุณประหยัดเวลาได้หลายร้อยชั่วโมงในภายหลัง

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

โดยสรุป:
เริ่มต้น:
คิดว่า
พูดคุย
ทดสอบ
เขียนเพียง
อ่าน
ทดสอบ
เขียน
แก้จุดบกพร่อง
GOTO เริ่มต้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.