ใครสามารถอธิบายอย่างง่าย ๆ ว่าอะไรคือรูปแบบของตัวทำลาย


33

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

บางทีด้วยความช่วยเหลือของคุณฉันสามารถเข้าใจมัน


คำตอบ:


33

ฟาวเลอร์บทความผู้ให้บริการไพรเมอร์ที่ดีและคำอธิบายนี้:

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

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

ป้อนคำอธิบายรูปภาพที่นี่

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


9

จากบทความนี้เกี่ยวกับCoralQueue :

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

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

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

package com.coralblocks.coralqueue.sample.queue;

import com.coralblocks.coralqueue.AtomicQueue;
import com.coralblocks.coralqueue.Queue;
import com.coralblocks.coralqueue.util.Builder;

public class Basics {

    public static void main(String[] args) {

        final Queue<StringBuilder> queue = new AtomicQueue<StringBuilder>(1024, new Builder<StringBuilder>() {
            @Override
            public StringBuilder newInstance() {
                return new StringBuilder(1024);
            }
        });

        Thread producer = new Thread(new Runnable() {

            private final StringBuilder getStringBuilder() {
                StringBuilder sb;
                while((sb = queue.nextToDispatch()) == null) {
                    // queue can be full if the size of the queue
                    // is small and/or the consumer is too slow

                    // busy spin (you can also use a wait strategy instead)
                }
                return sb;
            }

            @Override
            public void run() {

                StringBuilder sb;

                while(true) { // the main loop of the thread

                    // (...) do whatever you have to do here...

                    // and whenever you want to send a message to
                    // the other thread you can just do:
                    sb = getStringBuilder();
                    sb.setLength(0);
                    sb.append("Hello!");
                    queue.flush();

                    // you can also send in batches to increase throughput:
                    sb = getStringBuilder();
                    sb.setLength(0);
                    sb.append("Hi!");

                    sb = getStringBuilder();
                    sb.setLength(0);
                    sb.append("Hi again!");

                    queue.flush(); // dispatch the two messages above...
                }
            }
        }, "Producer");

        Thread consumer = new Thread(new Runnable() {

            @Override
            public void run() {

                while (true) { // the main loop of the thread

                    // (...) do whatever you have to do here...

                    // and whenever you want to check if the producer
                    // has sent a message you just do:

                    long avail;
                    while((avail = queue.availableToPoll()) == 0) {
                        // queue can be empty!
                        // busy spin (you can also use a wait strategy instead)
                    }

                    for(int i = 0; i < avail; i++) {
                        StringBuilder sb = queue.poll();
                        // (...) do whatever you want to do with the data
                        // just don't call toString() to create garbage...
                        // copy byte-by-byte instead...
                    }
                    queue.donePolling();
                }
            }
        }, "Consumer");

        consumer.start();
        producer.start();
    }
}

คำเตือน:ฉันเป็นหนึ่งในนักพัฒนาของ CoralQueue


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