How can two threads access a shared buffer array with minimal blocking? (WITH#)

I am working on an image processing application where I have two threads on top of my main thread:

1 - CameraThread , which captures images from a webcam and writes them to the clipboard

2 - ImageProcessingThread , which takes the last image from this buffer for filtering.

The reason this is multithreading is because speed is critical, and I need CameraThread to continue to capture images and make the last capture ready to capture using ImageProcessingThread while it is still processing the previous image.

My problem is finding a quick and thread-safe way to access this regular buffer, and I realized that ideally it should be a triple buffer (image [3]), so if ImageProcessingThread is slow, then CameraThread can continue to write on two other images and vice versa.

Which locking mechanism would be most suitable for this to be thread safe?

I looked at the lock statement, but it looks like it will make a block of threads, expecting one more to be completed, and that will be against the triple buffering point.

Thanks in advance for any idea or advice.

J.

+3
source share
7 answers

- .

.NET 4, IProducerConsumerCollection<T> .

, , - First-In First-Out,

+8

, , , "", , , . , "" , , , .

, FIFO (First in First Out), , , , . , .

, , . , , , , ..

+3

, , , . , .
"" , , .

, .
dotNET4, ConcurrentQuue.

+2

, lock free queues.

. , .

, , . , ( ), . , , .

: , , , .

+1

, concurrency. - - , .. concurrency:

, , " " . "MailboxThread", jane.

, , MailboxThreads, ():

let filter =
    while true
        let image = getNextMsg() // blocks until the next message is recieved
        process image

let camera(filterMailbox) =
    while true
        let image = takePicture()
        filterMailbox.SendMsg(image) // sends a message asyncronous

let filterMailbox = Mailbox.Start(filter)
let cameraMailbox = Mailbox.Start(camera(filterMailbox))

, - . , . filterMailbox , .

MailboxThread. , , , , ( ).

, , . enqueing dequeuing , .

0

.

, .

. , 1 1 , "" . , . : 1

:

int Status = 0;//0 = ; 1 =

Buffer1 = []

Buffer2 = []

Buffer3 = []

BufferTmp = null

thread1 {

while(true)
{
    WriteData(Buffer1);
    if (Status == 0)
    {
        BufferTmp = Buffer1;
        Buffer1 = Buffer2;
        Buffer2 = BufferTmp;
        Status = 1;
    }
}

}

thread2 {

while(true)
{
    ReadData(Buffer3);
    if (Status == 1)
    {
        BufferTmp = Buffer1;
        Buffer2 = Buffer3;
        Buffer3 = BufferTmp;
        Status = 0;
    }
}

}

, writedata , . .

In addition, you might need thread.sleep (1) in the ELSE statement to accompany IF statements, otherwise one single-core processor, a spinning thread, will increase the delay before another thread is assigned. eg. The write stream can start 2-3 times before the read stream is assigned, because the planners see that the write stream is doing the “work”

0
source

Source: https://habr.com/ru/post/1738506/


All Articles