Double buffering queue to reduce the competition for locks

Source: Internet
Author: User

Double buffering queue to reduce the competition for locks

In the daily development, log records are essential. But we also know that writing logs for the same text can only be written in a single thread, so we often use a simple lock lock to ensure that only one thread writes the log information. However, in the multi-threaded to write log information, because the logging information is required for I/O interaction, resulting in the time we occupy the lock longer, resulting in a large number of threads blocking and waiting.

In this scenario, we think about what we can do to make sure that when there are multiple threads to write the log, we are able to queue them in sequence without using the lock. This time we can consider using a double buffer queue to complete.

The so-called double-buffered queue is two queues, one is dedicated to the data write, the other is specifically responsible for data reading, when the logical thread reads the data, it is responsible for the queue of the I/O thread to Exchange.

How do we use this buffer queue to do what we want?

When there are multiple threads writing the log, this time we want to write the information in the queue we are responsible for writing, and then the logical read line Cheng to non-blocking. The logical-read thread is now ready to start working. (The queue at the beginning of the logical read is empty) after the logical read thread reads the data from his own queue (and executes some logic), the reference to the logical read queue and the queue responsible for the write are exchanged for reference. This is a simple idea of a double-buffered queue implementation. The specific implementation code is as follows:

  

User

    public class Doublequeue {private concurrentqueue<user> _writequeue;        Private concurrentqueue<user> _readqueue;        private volatile concurrentqueue<user> _currentqueue;        Private AutoResetEvent _dataevent;        Private ManualResetEvent _finishedevent;        Private ManualResetEvent _producerevent;            Public Doublequeue () {_writequeue = new concurrentqueue<user> ();            _readqueue = new concurrentqueue<user> ();            _currentqueue = _writequeue;            _dataevent = new AutoResetEvent (false);            _finishedevent = new ManualResetEvent (true);            _producerevent = new ManualResetEvent (true);        Task.Factory.StartNew (() = Consumerqueue (), taskcreationoptions.none);            public void Producerfunc (user user) {_producerevent.waitone ();            _finishedevent.reset ();            _currentqueue.enqueue (user);            _dataevent.set (); _finishedEvent.set ();            } public void Consumerqueue () {concurrentqueue<user> consumerqueue;            User user;            int allcount = 0;            Stopwatch watch = Stopwatch.startnew ();                while (true) {_dataevent.waitone ();                    if (_currentqueue.count > 0) {_producerevent.reset ();                    _finishedevent.waitone ();                    Consumerqueue = _currentqueue; _currentqueue = (_currentqueue = = _writequeue)?                    _readqueue: _writequeue;                    _producerevent.set ();                        while (Consumerqueue.count > 0) {if (Consumerqueue.trydequeue (out user)) {FluentConsole.White.Background.Red.Line (user.                            ToString ());                        allcount++; } FluentConsole.White.Background.Red.Line($ "Current number {Allcount. ToString ()}, which cost {watch.                        Elapsedmilliseconds.tostring ()}ms; ");                    System.Threading.Thread.Sleep (20); }                }            }        }    }

Fluentconsole is an output plugin for a console application, open source, interested in being able to play on your own.

output-side code

The first is performed using a double-buffered queue, and the second is performed using a lock lock. The following are the first method and CPU consumption when the second method executes.

We can see that with double queue buffering we reduce the CPU occupancy. But we may increase the time of execution.

Reference article: Http://www.codeproject.com/Articles/27703/Producer-Consumer-Using-Double-Queues

Someone else had thought about it in the 08, and I just had a little bit of an idea right now.

SOURCE download

Double buffering queue to reduce the competition for locks

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.