ภาษาซิงโครนัสกับอะซิงโครนัส

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

พื้นที่ใดที่พวกเขาแข็งแกร่งกว่าเมื่อเปรียบเทียบกับที่อื่นและพื้นที่ที่พวกเขาตกอยู่คืออะไร?


person Umesh    schedule 18.12.2009    source แหล่งที่มา
comment
ภาษาสามารถเป็นแบบอะซิงโครนัสได้อย่างไร?   -  person Azeem.Butt    schedule 18.12.2009
comment
@NSD - สิ่งที่เขาหมายถึงคือ flex ไม่เคยบล็อก - การดำเนินการทั้งหมดที่สามารถบล็อกบนแพลตฟอร์มอื่น ๆ จะถูกนำไปใช้แบบอะซิงโครนัส   -  person Grokys    schedule 18.12.2009
comment
คุณมีคำจำกัดความสำหรับภาษาการดำเนินการแบบซิงโครนัสหรือไม่? หรือคุณเพียงตีความธรรมชาติของ Flex ที่ขับเคลื่อนด้วยเหตุการณ์ (ซึ่งพบได้ใน GUI API อื่น ๆ เกือบทั้งหมดรวมถึง Java ด้วย) เป็นแบบอะซิงโครนัส   -  person kdgregory    schedule 18.12.2009
comment
@ kdgregory- ฉันไม่เข้าใจว่าทำไมคุณถึงเปลี่ยนกลไกการดำเนินการของ flex โดยชื่อที่ขับเคลื่อนโดยธรรมชาติของ flex มันค่อนข้างยากสำหรับฉันที่จะแยกแยะเนื่องจากเป็นภาษาแรกที่ฉันเล่นซึ่งมีพฤติกรรมแบบนี้ ภาษาอื่นๆ เช่น c และ all จะรอให้เมธอดที่เรียกเสร็จสิ้นเพื่อไปยังบรรทัดถัดไป แต่ในนี้มันไม่ใช่ แต่ดิ้นดำเนินการในเธรดซึ่งทำให้การดำเนินการเร็วขึ้น (ฉันคิดว่า) แต่พวกเขายังมีผู้ฟังเหตุการณ์ที่ต้องการให้ผู้ฟังทำงานต่อไปซึ่งกินรอบ CPU - ฉันถูกต้องหรือไม่ แล้วข้อดีคืออะไร?   -  person Umesh    schedule 18.12.2009
comment
ฉันไม่คิดว่า Flex เป็นภาษา ฉันเดาว่านี่คือพื้นที่ที่ฉันตก   -  person Azeem.Butt    schedule 18.12.2009
comment
ภาษา C สามารถมีวิธีแบบอะซิงโครนัสได้ เช่นเดียวกับภาษาส่วนใหญ่ บางทีคุณอาจสับสนภาษากับกรอบงาน?   -  person Peter Recore    schedule 19.12.2009
comment
@ Azeem.Butt ตัวอย่าง Wierd, javascript บังคับสไตล์อะซิงก์ด้วย 'เธรดเดี่ยว'   -  person ceram1    schedule 01.01.2015


คำตอบ (3)


ฉันใช้เวลาส่วนใหญ่ในปีที่แล้วในการเขียนโค้ดใน Silverlight ซึ่งหมายความว่าฉันใช้เวลาอย่างมากในการคิด (และต่อสู้กับ) ปัญหาเดียวกันกับที่คุณอธิบาย

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

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

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

อัปเดต 2014.09.23 -

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

  • หากคุณใช้ภาษาเช่น C# หรือ F# ที่รองรับอะซิงโครนัสระดับเฟิร์สคลาส สิ่งนี้จะง่ายขึ้นมาก อย่างน้อยเมื่อคุณคาดศีรษะด้วยรูปแบบ async/await แปลกๆ ความสามารถในการวนซ้ำการโทรแบบอะซิงโครนัสได้อย่างง่ายดาย และสรุปทุกอย่างด้วยการ try/catch แบบง่ายๆ นั้นน่าทึ่งมากหากคุณเคยต้องทำแบบเก่า

  • หากคุณไม่ได้ใช้ภาษาที่รองรับ async ระดับเฟิร์สคลาส ให้เริ่มใช้ภาษาใดก็ได้ที่สนับสนุน promise หรือ future หรือ task ที่ภาษานั้นมีให้ (เช่น $.Deferred() ของ JQuery หรือ $q.defer() ของ Angular สิ่งเหล่านี้สะอาดกว่ามากและมีโครงสร้างที่ดีกว่าภาษาใด โดยทั่วไปคุณจะได้รับการโทรกลับ

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

person Ken Smith    schedule 18.12.2009
comment
มีวิธีปฏิบัติในการเขียนแอปพลิเคชันในกรอบงานที่ขับเคลื่อนด้วยเหตุการณ์หรือไม่? - person Umesh; 18.12.2009
comment
สมมติว่าสำนวนแลมบ์ดาเป็นเพื่อนใหม่ที่ดีที่สุดของคุณ :-) นอกจากนั้น ฉันคิดว่ารูปแบบและแนวทางปฏิบัติส่วนใหญ่จะแตกต่างกันไปในแต่ละกรอบงาน ขึ้นอยู่กับข้อจำกัดที่วางไว้กับคุณ ตัวอย่างเช่น ในโลกของ Silverlight ฉันพบว่ามันช่วยได้อย่างมากในการรวมรูปแบบที่ขับเคลื่อนด้วยเหตุการณ์ที่ Microsoft จัดเตรียมไว้ให้ด้วยรูปแบบที่มุ่งเน้นการโทรกลับ (และโดยปกติแล้วฉันมักจะใช้การโทรกลับเป็นนิพจน์แลมบ์ดา) ทำให้ง่ายต่อการปฏิบัติตามตรรกะของแอปพลิเคชันได้ง่ายขึ้นอย่างมาก ฉันไม่ได้ทำ Flex มากพอที่จะรู้ว่าอะไรเหมาะสม - person Ken Smith; 19.12.2009
comment
ขอบคุณมากสำหรับคำอธิบายของคุณเซอร์ ฉันมาจากโลกแห่งการซิงค์และคิดอยู่ตลอดเวลาว่าโค้ดอะซิงก์สกปรกแค่ไหน ฉันจะรับคำแนะนำของคุณและเข้าสู่โหนด ขอบคุณ! - person Capitan Empanada; 11.07.2020

(ละเว้นการสนทนาระดับความหมาย เช่น "ภาษาซิงค์/อะซิงค์")

"เฟรมเวิร์ก" ที่สร้างขึ้นบน "ภาษา" (ไม่ว่าจะเป็นอะไรก็ตาม) ควรจะสามารถจัดการกับกรณีดังกล่าวได้ (โฟลว์โปรแกรม sync/async) เพื่อให้มีประโยชน์ (อ่าน: $ wise)

สำนวนแบบอะซิงโครนัสมีความเหมาะสมในทุกระดับ

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

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

person jldupont    schedule 18.12.2009
comment
เป็นจริงหากคุณคิดว่ากรณีทดสอบหลายกรณีพร้อมกัน แต่เท่าที่ฉันคิดได้ พวกเขาจะช่วยเฉพาะกรณีทดสอบเท่านั้น ในชีวิตจริงและต่อๆ ไป สิ่งที่เป็นอยู่นั้นขึ้นอยู่กับสิ่งที่เกิดขึ้นตอนนี้หรือผลลัพธ์ของสิ่งนั้นล้วนๆ แล้วอะซิงโครนัสจะกลายเป็นความสำเร็จได้อย่างไร? - person Umesh; 18.12.2009
comment
@Umesh: สิ่งที่เกิดขึ้นตอนนี้คือแซนด์บ็อกซ์ที่สร้างขึ้นโดยเหตุการณ์การทำให้เป็นอนุกรมปลอม มันเป็นคำถามของกรอบอ้างอิง (ดังที่เราเรียกกันในวิชาฟิสิกส์) ส่วนเรื่องที่อะซิงโครนัสจะกลายเป็นความสำเร็จได้อย่างไร ฉันต้องบอกว่าฉันไม่ได้ติดตามคุณ คุณช่วยกรุณาอธิบายหน่อยได้ไหม? - person jldupont; 18.12.2009
comment
คำอธิบายของคุณทำให้ฉันชัดเจน โปรดลืมคำถามของฉัน ขอบคุณ - person Umesh; 18.12.2009
comment
@Umesh: คุณต้องการให้แถบเมนูบนเว็บเบราว์เซอร์ของคุณไม่ตอบสนองทุกครั้งที่เบราว์เซอร์ของคุณส่งคำขอเครือข่ายหรือไม่? มีสถานที่มากมายที่สิ่งต่าง ๆ สามารถเกิดขึ้นได้โดยไม่รู้ผลลัพธ์ของการโทรแบบสุ่ม - person tloach; 18.12.2009
comment
@tloach - ฉันเห็นด้วย แต่แค่คิด.. วิธีการแบบอะซิงโครนัสจะแก้ปัญหาที่คุณถามได้ แต่เพื่อให้บรรลุฟังก์ชันการทำงานที่ต้องเป็นแบบซิงโครนัส เรากำลังจัดกิจกรรมและทั้งหมดเป็นภาษาอะซิงโครนัส (สคริปต์ flex/action) ดังนั้นคำถามของฉันสำหรับ jidupont คืออัตราการเกิดเหตุการณ์แบบซิงโครนัสเป็นเท่าใดเมื่อเปรียบเทียบกับเหตุการณ์แบบอะซิงโครนัส หมายถึงวิธีใดที่ภาษาโปรแกรมจำเป็นต้องใช้เป็นพื้นฐานและให้อีกวิธีหนึ่งเป็นตัวเลือกที่คุณสามารถนำไปใช้ได้ (ฉันคิดว่าฉันชัดเจน) - person Umesh; 18.12.2009

ฉันคิดว่ามันไม่เกี่ยวกับภาษา แต่เกี่ยวกับกรอบงาน

ประเด็นโต้แย้ง:

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

person Javier    schedule 18.12.2009
comment
มันหมายถึงการปรับปรุงประสิทธิภาพโดยการทำงานแบบขนานและใช้ฮาร์ดแวร์จริงๆ หรือไม่ แต่ค่าใช้จ่ายในการฟังการโทรกลับจากเธรดหลักคืออะไร พวกเขามีด้านที่ดีกว่าไหม? - person Umesh; 18.12.2009
comment
@Umesh: คุณไม่ฟังการโทรกลับจากเธรดอื่น เธรดจะเรียกการโทรกลับโดยตรง ค่าใช้จ่ายจะเหมือนกับการเรียกใช้ฟังก์ชันอื่นๆ - person tloach; 18.12.2009