อะซิงโครนัสกับการไม่ปิดกั้น


373

ความแตกต่างระหว่างการโทรแบบอะซิงโครนัสและการไม่บล็อกคืออะไร ระหว่างการบล็อคและการโทรแบบซิงโครนัส (พร้อมตัวอย่าง)


4
ที่เกี่ยวข้อง: stackoverflow.com/a/9489547/194894
Flow

1
ฉันมีความเข้าใจที่ดีเกี่ยวกับความแตกต่างในขณะที่อ่านหนังสือ <Unix Networking Programming> Col ​​1, ตอนที่ 6
Bin

2
บทความที่น่าสนใจ: ประสิทธิภาพของโปรแกรม Boost ใช้ไม่ตรงกัน I / O มันแบ่งกระบวนทัศน์ของ I / O เป็น 4 หมวดหมู่: (1) การบล็อก + ซิงโครนัส (2) การไม่บล็อก + ซิงโครนัส (3) การบล็อก + อะซิงโครนัสและ (4) การบล็อก + อะซิงโครนัส
MS Dousti

@MSDousti ฉันถูกบอกว่านี่เป็นความผิดในบางวิธีจากผู้เชี่ยวชาญของ Google
Rick

@MSDousti หลังจากการศึกษาบางอย่างฉันคิดว่าไม่มีการรวม (3) และ (2) ตามที่คุณอธิบายไว้ในความคิดเห็น ตรวจสอบคำจำกัดความของอะซิงโครนัสมันกำลังพูดถึงสิ่งเดียวกันกับการไม่บล็อก ในขณะที่คุณสามารถเห็นคำตอบด้านบนก็ยืนยันความคิดเห็นของฉัน ฟังก์ชันการเรียกและการเรียกกลับเป็นเพียงวิธี / รูปแบบในการใช้ Asynchronous ใช่ฉันกำลังบอกว่าการบล็อกการซิงโครนัสและการไม่บล็อกอะซิงโครนัสเป็นคำพ้องความหมาย 2 คู่
Rick

คำตอบ:


304

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

ตัวอย่างเช่นใน classic sockets API ซ็อกเก็ตที่ไม่ปิดกั้นเป็นซ็อคเก็ตที่ส่งคืนได้ทันทีพร้อมกับข้อความแสดงข้อผิดพลาด "จะบล็อก" พิเศษในขณะที่ซ็อกเก็ตการบล็อกจะปิดกั้น คุณต้องใช้ฟังก์ชั่นแยกต่างหากเช่นselectหรือpollเพื่อค้นหาว่าเมื่อใดเวลาที่เหมาะสมในการลองใหม่

แต่ซ็อกเก็ตแบบอะซิงโครนัส (รองรับโดยซ็อกเก็ต Windows) หรือรูปแบบอะซิงโครนัส IO ที่ใช้ใน. NET จะสะดวกกว่า คุณเรียกวิธีการเพื่อเริ่มการทำงานและกรอบการโทรกลับเมื่อทำเสร็จแล้ว แม้ที่นี่จะมีความแตกต่างพื้นฐาน Asynchronous Win32 ซ็อกเก็ต "marshal" ผลลัพธ์ของพวกเขาไปยังเธรด GUI เฉพาะโดยผ่านข้อความหน้าต่างในขณะที่. NET asynchronous IO นั้นเป็นเธรดฟรี

ดังนั้นพวกเขาจึงไม่ได้หมายถึงสิ่งเดียวกันเสมอไป เพื่อกลั่นตัวอย่างซ็อกเก็ตเราสามารถพูดได้:

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

พร้อมสถานะ IO ไม่ใช่สถานะเสร็จสมบูรณ์ IO; บน Linux ดู libaio
จะ

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

2
การติดตามผล Q: คำตอบดูเหมือนจะสร้างความแตกต่างสองประการระหว่างคำศัพท์ ขั้นแรกการแจ้งเตือน: การไม่บล็อกหมายถึงแอปพลิเคชันจะต้องตรวจสอบอีกครั้งในภายหลัง (การสำรวจ) ในขณะที่ async หมายถึงเราสามารถลืมมันได้และอาศัยกรอบ / ระบบปฏิบัติการเพื่อแจ้งให้เราทราบผ่านการติดต่อกลับ ประการที่สองการกระทำ: การปิดกั้นไม่ได้ทำอะไรเลยอย่างแน่นอน แต่กลับข้อผิดพลาดในขณะที่ async คิวการกระทำหรือ "ในพื้นหลัง" ในบางแง่มุม ความแตกต่างใดสำคัญกว่าในการแยกความหมายของคำศัพท์ ความแตกต่างทั้งสองมีความเกี่ยวข้องอย่างยิ่งกับคำหนึ่งหรือไม่ หรือมันคลุมเครือ?
ชาด NB

2
@ChadNB - ตามเงื่อนไขการไม่บล็อกมีความเกี่ยวข้องอย่างยิ่งกับการสำรวจ เกี่ยวกับคำถามว่า API "จดจำ" ความพยายามในการโทรหาคุณหรือไม่: เหตุผลเดียวที่ API ที่ต้องจำคือเพื่อโทรกลับหาคุณ หากคุณกำลังจะเรียกมันให้ทำการสำรวจความคิดเห็นอีกครั้งคุณต้องรักษาสถานะที่จำเป็นเพื่อให้ทราบว่าจะทำการโทรครั้งต่อไปดังนั้น API จะไม่เพิ่มมูลค่าใด ๆ โดยการรักษาสถานะไว้ด้วย
Daniel Earwicker

6
แทนที่จะบอกว่าการโทรแบบไม่บล็อคจะส่งกลับ "ข้อผิดพลาด" ฉันคิดว่ามันจะแม่นยำกว่าถ้าบอกว่าการโทรแบบไม่บล็อคจะทำได้มากเท่าที่จะทำได้ในทันทีและจากนั้นก็ระบุว่ามันทำได้มากแค่ไหน สำหรับการดำเนินการบางอย่างปริมาณงานที่ทำจะเป็น "ทุกอย่าง" หรือ "ไม่มีอะไร" แต่การดำเนินการอื่น ๆ (เช่นสตรีม I / O) อาจส่งคืนข้อบ่งชี้เชิงปริมาณ การไม่บล็อกคือความหมายเทียบเท่ากับการปิดกั้นด้วยการหมดเวลาสั้น ๆหากการใช้งานการบล็อก I / O จะช่วยให้การดำเนินการซึ่งหมดเวลาที่จะลองใหม่ในภายหลังได้อย่างราบรื่น (บางคนทำบางคนไม่ได้)
supercat

56

ซิงโครนัส / อะซิงโครนัสคือการอธิบายความสัมพันธ์ระหว่างสองโมดูล
การปิดกั้น / ไม่ปิดกั้นคือการอธิบายสถานการณ์ของหนึ่งโมดูล

ตัวอย่าง:
โมดูล X: "I"
โมดูล Y: "bookstore"
X ถาม Y: คุณมีหนังสือชื่อ "c ++ primer" หรือไม่?

1) การบล็อก: ก่อนที่ Y จะตอบ X, X จะรอคำตอบอยู่ที่นั่น ตอนนี้ X (หนึ่งโมดูล) กำลังปิดกั้น X และ Y เป็นสองเธรดหรือสองโพรเซสหรือหนึ่งเธรดหรือหนึ่งโพรเซส? เราไม่รู้

2) การไม่บล็อก: ก่อนที่ Y จะตอบ X, X จะออกจากที่นั่นและทำสิ่งอื่น ๆ X อาจกลับมาทุกสองนาทีเพื่อตรวจสอบว่า Y ทำงานเสร็จหรือไม่? หรือ X จะไม่กลับมาจนกว่า Y เรียกเขาว่า? เราไม่รู้เรารู้เพียงว่า X สามารถทำสิ่งอื่นก่อนที่ Y จะทำงานเสร็จ ที่นี่ X (หนึ่งโมดูล) ไม่มีการปิดกั้น X และ Y เป็นสองเธรดหรือสองโพรเซสหรือหนึ่งโพรเซส? เราไม่รู้ แต่เรามั่นใจว่า X และ Y ไม่สามารถเป็นหนึ่งเธรด

3) แบบซิงโครนัส: ก่อนที่ Y จะตอบ X, X จะยังรอคำตอบอยู่ หมายความว่า X ไม่สามารถดำเนินการต่อได้จนกว่า Y จะทำงานเสร็จ ตอนนี้เราพูดว่า: X และ Y (สองโมดูล) เป็นแบบซิงโครนัส X และ Y เป็นสองเธรดหรือสองโพรเซสหรือหนึ่งเธรดหรือหนึ่งโพรเซส? เราไม่รู้

4) แบบอะซิงโครนัส: ก่อนที่ Y จะตอบ X, X จะออกจากที่นั่นและ X สามารถทำงานอื่นได้ X จะไม่กลับมาจนกว่า Y จะเรียกเขาว่า ตอนนี้เราพูดว่า: X และ Y (สองโมดูล) เป็นแบบอะซิงโครนัส X และ Y เป็นสองเธรดหรือสองโพรเซสหรือหนึ่งโพรเซส? เราไม่รู้ แต่เรามั่นใจว่า X และ Y ไม่สามารถเป็นหนึ่งเธรด


โปรดให้ความสนใจกับประโยคสองประโยคข้างต้น เหตุใดประโยคตัวหนาใน 2) มีสองกรณีในขณะที่ประโยคตัวหนาใน 4) มีเพียงหนึ่งกรณี? นี่คือกุญแจสำคัญของความแตกต่างระหว่างการไม่บล็อกและอะซิงโครนัส

นี่คือตัวอย่างทั่วไปเกี่ยวกับการไม่บล็อก & ซิงโครนัส:

// thread X
while (true)
{
    msg = recv(Y, NON_BLOCKING_FLAG);
    if (msg is not empty)
    {
        break;
    }
    sleep(2000); // 2 sec
}

// thread Y
// prepare the book for X
send(X, book);

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

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

ตัวอย่างเช่นเราอาจออกแบบสถาปัตยกรรมประเภทนี้:

// Module X = Module X1 + Module X2
// Module X1
while (true)
{
    msg = recv(many_other_modules, NON_BLOCKING_FLAG);
    if (msg is not null)
    {
        if (msg == "done")
        {
            break;
        }
        // create a thread to process msg
    }
    sleep(2000); // 2 sec
}
// Module X2
broadcast("I got the book from Y");


// Module Y
// prepare the book for X
send(X, book);

ในตัวอย่างที่นี่เราสามารถพูดได้ว่า

  • X1 ไม่ใช่การปิดกั้น
  • X1 และ X2 เป็นแบบซิงโครนัส
  • X และ Y เป็นแบบอะซิงโครนัส

หากคุณต้องการคุณสามารถอธิบายหัวข้อเหล่านั้นที่สร้างใน X1 ด้วยคำสี่คำ

สิ่งที่สำคัญกว่าคือเมื่อใดที่เราจะใช้แบบซิงโครนัสแทนที่จะเป็นแบบอะซิงโครนัส? เราจะใช้การบล็อกแทนการไม่บล็อกเมื่อใด

ทำไม Nginx จึงไม่ทำการปิดกั้น ทำไม Apache ปิดกั้น

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


7
IMO คำตอบที่ดีที่สุดเพราะมันจับสาระสำคัญของแนวคิด: ความสัมพันธ์ระหว่างหนึ่งหรือสองผู้เข้าร่วม
Fábio

ทั้งใน 1 และ 3 Y ทำหน้าที่เป็นทรัพยากร จำกัด ไม่มี Y อีกแล้วที่จะช่วย X
UVM

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

17
เมื่อเกี่ยวข้องกับ I / O อะซิงโครนัสมักจะไม่ "ขนาน" หรือ "เธรดอื่น" ส่วนใหญ่เป็นการแจ้งเตือนตาม นั่นคือ: อย่าปิดกั้นไม่ต้องสำรวจความคิดเห็นเพียงแค่รับสัญญาณ แน่นอนมันอาจเป็นที่ถกเถียงกันอยู่ว่าสัญญาณมาจาก 'โลกแห่งความจริง' ซึ่งสามารถคิดได้ว่าเป็น 'หัวข้ออื่น' ...
Javier

ใช่แล้วเราสามารถโต้แย้งถ้อยคำที่แน่นอนได้ทั้งวัน :)
Nikolai Fetissov

แต่คุณจะอธิบาย AIO ใน Linux ได้อย่างไร ซึ่งใช้ทั้ง Async และ non-blocking ลิงก์ AIO
Djvu

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

2
Async ไม่ได้หมายความว่ามันจะทำแบบขนานดูโพสต์ที่ยอดเยี่ยมนี้ใน stackoverflow เกี่ยวกับการเขียนโปรแกรมพร้อมกันและขนาน
BARJ

17

วางคำถามนี้ในบริบทของ NIO และ NIO.2 ใน java 7 async IO เป็นขั้นตอนที่สูงกว่าการไม่บล็อก กับ Java NIO non-blocking สายหนึ่งจะตั้งทุกช่อง (SocketChannel, ServerSocketChannel, FileChannel ฯลฯ ) AbstractSelectableChannel.configureBlocking(false)ดังกล่าวโดยการเรียก อย่างไรก็ตามหลังจากที่สาย IO เหล่านั้นกลับมาคุณจะยังคงต้องควบคุมการตรวจสอบเช่นถ้าและเมื่อใดที่จะอ่าน / เขียนอีกครั้งเป็นต้น
เช่น

while (!isDataEnough()) {
    socketchannel.read(inputBuffer);
    // do something else and then read again
}

ด้วยอะซิงโครนัส api ใน java 7 การควบคุมเหล่านี้สามารถทำได้หลากหลายวิธีมากขึ้น หนึ่งใน 2 CompletionHandlerวิธีคือการใช้งาน ขอให้สังเกตว่าการreadโทรทั้งสองเป็นการไม่ปิดกั้น

asyncsocket.read(inputBuffer, 60, TimeUnit.SECONDS /* 60 secs for timeout */, 
    new CompletionHandler<Integer, Object>() {
        public void completed(Integer result, Object attachment) {...}  
        public void failed(Throwable e, Object attachment) {...}
    }
}

3
FileChannelไม่สามารถเลือกได้และไม่สามารถกำหนดค่าเป็นไม่บล็อก
michaelliu

15

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

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

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

ขออภัยฉันไม่เชื่อว่ามีคำตอบเดียวที่ถูกต้องซึ่งเป็นความจริงทั่วโลก


1
+1 คำตอบที่ดี คนจะต้องตระหนักว่า "ตรงกัน" อาจหมายถึงทั้งที่ไม่ใช่การปิดกั้นหรือ (เหตุการณ์ตาม / โทรกลับ) วิธีการ asynch ไมโครซอฟท์
วิศวกร

14

การโทรที่ไม่บล็อกจะส่งคืนทันทีที่มีข้อมูลใด ๆ : จำนวนไบต์ทั้งหมดที่ร้องขอน้อยกว่าหรือไม่มีเลย

การเรียกแบบอะซิงโครนัสร้องขอการถ่ายโอนที่จะดำเนินการทั้งหมด (ทั้งหมด) แต่จะเสร็จสมบูรณ์ในบางครั้งในอนาคต


การไม่บล็อกไม่ส่งคืนผลลัพธ์ใด ๆ เลย
CEO ที่ Apartico

9

ไม่ปิดกั้น: ฟังก์ชั่นนี้จะไม่รอในขณะที่อยู่ในกอง

อะซิงโครนัส: งานอาจดำเนินการต่อในนามของการเรียกฟังก์ชันหลังจากการโทรนั้นออกจากสแต็ก


1
@Marenz หมายความว่าคุณไม่สามารถปิดกั้น io โดยตรงด้วยการโทรแบบ posix แต่นั่นไม่ได้เปลี่ยนความหมายที่เขาให้ที่นี่
tmc

@Marenz ซึ่งหมายความว่าเฉพาะแฟล็กที่ถูกละเว้นสำหรับไฟล์ ไม่ส่งผลกระทบต่อความหมายของคำตอบนี้
มาร์ควิสแห่ง Lorne

8

ซิงโครนัสหมายถึงการเกิดขึ้นในเวลาเดียวกัน

อะซิงโครนัสหมายถึงไม่เกิดขึ้นในเวลาเดียวกัน

นี่คือสิ่งที่ทำให้เกิดความสับสนครั้งแรก ซิงโครนัสเป็นสิ่งที่เรียกว่าขนาน ในขณะที่อะซิงโครนัสเป็นลำดับทำเช่นนี้แล้วทำ

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

ทางออกที่ง่ายที่สุดเรียกว่าการบล็อก

การบล็อกคือเมื่อคุณเลือกที่จะรอให้สิ่งอื่น ๆ นั้นเสร็จแล้วส่งกลับคำตอบให้คุณก่อนที่จะดำเนินการตามที่ต้องการ

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

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

นั่นคือสิ่งที่โซลูชันสองตัวอื่นรู้จักกันในชื่อ non-blocking และ asynchronous

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

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

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

ที่นี่ไม่ตรงกัน

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

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

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

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

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

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

แก้ไข:

แม้ว่านี่จะนานแล้ว แต่ฉันก็อยากให้มันสมบูรณ์ดังนั้นฉันจะเพิ่มอีกสองจุด

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

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

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

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


ไม่แน่ใจว่าทำไมคุณถึงพูดว่า "การซิงโครนัสหมายถึงการเกิดขึ้นพร้อมกัน"? แนวคิดทั้งหมดคือมันไม่พร้อมกันหรือไม่เกิดขึ้นในเวลาเดียวกัน
Helsing

มันเป็นการเปรียบเทียบที่ยอดเยี่ยม! คุณเพิ่งปิ้งมัน!
d-coder

@Helsing นั่นคือความหมายของคำอย่างแท้จริง ซิงโครนัสหมายถึงเวลาเดียวกันและไม่ตรงกันในเวลาเดียวกัน: p เหตุผลบางอย่างไม่ตรงกันเพราะมันไม่สามารถเกิดขึ้นได้ในเวลาเดียวกันมันต้องเกิดขึ้นก่อนหรือหลัง หากมันเกิดขึ้นในเวลาเดียวกันคุณสามารถทำให้มันขนานกันหรือทำมันในลำดับใดก็ได้และคุณไม่จำเป็นต้องทำการซิงโครไนซ์อย่างชัดเจน นั่นเป็นสาเหตุที่การเขียนโปรแกรม async นั้นเกี่ยวกับการทำสิ่งนี้แล้วรอสิ่งเหล่านี้แล้ว ฯลฯ เพราะไม่มีสิ่งเหล่านี้เกิดขึ้นพร้อมกันในเวลาเดียวกัน
Didier A.

@Helsing ยังเกิดขึ้นพร้อมกันไม่ได้เป็นแบบขนาน มันไม่ได้หมายความว่ามีสองสิ่งเกิดขึ้นในเวลาเดียวกันมันหมายถึงความคืบหน้ามากกว่าหนึ่งสิ่งที่เกิดขึ้นก่อนที่สิ่งใด ๆ จะเสร็จสิ้น ที่สามารถทำได้ด้วยการขนานหรือเพียงแค่สลับ interleaving หรือที่รู้จักการสลับงาน
Didier A.

4

การบล็อกการโทร: การควบคุมจะส่งกลับเฉพาะเมื่อการโทรสิ้นสุดลง

ไม่บล็อคการโทร: การควบคุมจะส่งกลับทันที หลังจากนั้นระบบปฏิบัติการจะแจ้งกระบวนการที่เรียกเสร็จสมบูรณ์


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

โปรแกรมอะซิงโครนัส : โปรแกรมที่ใช้การโทรแบบไม่บล็อค สามารถมี 1 เธรดเท่านั้นและยังคงเป็นแบบโต้ตอบ


1
การโทรที่ไม่บล็อก: การควบคุมจะส่งกลับหลังจากทำมากที่สุดเท่าที่จะทำได้ทันที วิธีการระบุว่าทำเสร็จแล้ว ซึ่งแตกต่างจากการโทรแบบอะซิงโครนัสซึ่งจะทำงานตามที่คุณอธิบายไว้สำหรับการบล็อกการโทร
supercat

0

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


0

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


-2

การปิดกั้น:การควบคุมกลับสู่การเรียกใช้ precess หลังจากการประมวลผลดั้งเดิม (ซิงค์หรือ async) เสร็จสมบูรณ์

ไม่ปิดกั้น:การควบคุมจะกลับสู่กระบวนการทันทีหลังจากการเรียก


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