บัฟเฟอร์แหวนเดี่ยวผู้ผลิตแบบหลายผู้ผลิต (MPSC) ซึ่งรองรับการทำงานของช่วงที่ต่อเนื่องกันและสามารถใช้งานได้อย่างสะดวกสำหรับการส่งข้อความ การดำเนินการถูกเขียนใน C11 และแจกจ่ายภายใต้ใบอนุญาต BSD 2 ข้อ
int ringbuf_setup(ringbuf_t *rbuf, unsigned nworkers, size_t length)
rbuf เป็นตัวชี้ไปยังวัตถุบัฟเฟอร์แหวนทึบแสง ผู้โทรมีหน้าที่จัดสรรพื้นที่สำหรับวัตถุนี้ โดยทั่วไปวัตถุจะได้รับการจัดสรรแบบไดนามิกหากใช้เธรดหรือสงวนไว้ในหน่วยความจำที่ใช้ร่วมกันหากใช้กระบวนการ ขนาดการจัดสรรสำหรับวัตถุจะได้รับโดยใช้ฟังก์ชัน ringbuf_get_sizes ส่งคืน 0 ในความสำเร็จและ -1 เมื่อความล้มเหลว void ringbuf_get_sizes(unsigned nworkers, size_t *ringbuf_obj_size, size_t *ringbuf_worker_size)
ringbuf_t ทึบแสงและเป็นทางเลือกโครงสร้าง ringbuf_worker_t ขนาดของโครงสร้าง ringbuf_t ขึ้นอยู่กับจำนวนของคนงานที่ระบุโดยพารามิเตอร์ nworkers ringbuf_worker_t *ringbuf_register(ringbuf_t *rbuf, unsigned i)
i เป็นหมายเลขคนงานเริ่มต้นที่ศูนย์ (เช่นจะเป็นมากกว่า nworkers ที่ใช้ในการตั้งค่า) ในความสำเร็จให้ส่งคืนตัวชี้ไปยังโครงสร้าง ringbuf_worker_t ทึบแสงซึ่งเป็นส่วนหนึ่งของบล็อกหน่วยความจำ ringbuf_t เมื่อความล้มเหลวส่งคืน NULL void ringbuf_unregister(ringbuf_t *rbuf, ringbuf_worker_t *worker)
ssize_t ringbuf_acquire(ringbuf_t *rbuf, ringbuf_worker_t *worker, size_t len)
ringbuf_produce เพื่อระบุว่า ไม่อนุญาตให้มีการโทรแบบซ้อนกัน void ringbuf_produce(ringbuf_t *rbuf, ringbuf_worker_t *worker)
size_t ringbuf_consume(ringbuf_t *rbuf, size_t *offset)
ringbuf_release เพื่อระบุว่า void ringbuf_release(ringbuf_t *rbuf, size_t nbytes)
ผู้บริโภคจะส่งคืนบล็อกที่ต่อเนื่องกันของช่วงที่ผลิตเช่นการโทร ringbuf_consume จะไม่ส่งคืนช่วงบางส่วน หากคุณนึกถึงช่วงที่ผลิตเป็นข้อความผู้บริโภคจะส่งคืนบล็อกของข้อความและสิ้นสุดที่ขอบเขตข้อความเสมอ พฤติกรรมดังกล่าวช่วยให้เราสามารถใช้การใช้งานบัฟเฟอร์วงแหวนนี้เป็นคิวข้อความ
การใช้งานได้รับการทดสอบอย่างกว้างขวางบนเครื่อง 24-core x86 ดูการทดสอบความเครียดสำหรับรายละเอียดเกี่ยวกับเทคนิค นอกจากนี้ยังให้ตัวอย่างว่ากลไกสามารถใช้สำหรับการส่งข้อความได้อย่างไร
การใช้งานบัฟเฟอร์วงแหวนนี้จะให้ช่วงพื้นที่ที่ต่อเนื่องกันสำหรับผู้ผลิตเสมอ มันสามารถทำได้โดยการล้อมรอบก่อนหากช่วงที่ร้องขอไม่พอดีในที่สุด ความหมายของสิ่งนี้คือการโทร ringbuf_acquire อาจล้มเหลวหากช่วงที่ร้องขอมากกว่าครึ่งหนึ่งของขนาดบัฟเฟอร์ ดังนั้นอาจจำเป็นต้องตรวจสอบให้แน่ใจว่าขนาดบัฟเฟอร์วงแหวนมีขนาดใหญ่อย่างน้อยสองเท่าของขนาดหน่วยการผลิตสูงสุด
ควรสังเกตว่าหนึ่งในการแลกเปลี่ยนการออกแบบดังกล่าวคือผู้บริโภคในปัจจุบันทำการสแกน O (N) ในรายชื่อผู้ผลิต
ผู้ผลิต:
if (( w = ringbuf_register ( r , worker_id )) == NULL )
err ( EXIT_FAILURE , "ringbuf_register" )
...
if (( off = ringbuf_acquire ( r , w , len )) != -1 ) {
memcpy ( & buf [ off ], payload , len );
ringbuf_produce ( r , tls );
}ผู้บริโภค:
if (( len = ringbuf_consume ( r , & off )) != 0 ) {
process ( & buf [ off ], len );
ringbuf_release ( r , len );
}