Jump to content

Queue and Concurrency


Recommended Posts

Hello All,

I am writing an application that will be creating a number of sub interfaces that run separately from the main interface once they have been started. I want to be able to send a message back to the main interface from the sub interfaces and I was thinking I would do this by sending a queue to the sub interfaces so that they could add queue elements and the main interface could de-queue elements. Does anybody know if having multiple threads enqueueing on a single queue causes concurrency issues? The order is not super important so if "n" simultaneous enqueues end up on the queue in a random order it doesn't matter so long as they all get on the queue and there is no change of them overwriting each other.

thanks,

Bernard

Link to comment

iHi,

That should work, as long as only one process is "dequeuing." An "user event" may also be useful for this application. This allows the main process to react quickly to both, messages and user interface events, without polling. The choice between a queue, and user even depends upon the function of the main process. (ie. polling, or non-polling)

Edited by SuperS_5
Link to comment

iHi,

That should work, as long as only one process is "dequeuing." An "user event" may also be useful for this application. This allows the main process to react quickly to both, messages and user interface events, without polling. The choice between a queue, and user even depends upon the function of the main process. (ie. polling, or non-polling)

Thanks, I am largely just doing proof of concept stuff at the moment but I was thinking that an event case will be running in each of the interfaces, the messages being generated by the event cases. then being processed at a single point

Link to comment

Hello,

The choice between a queue, and user even depends upon the function of the main process. (ie. polling, or non-polling)

Implementing a non polling process based on queue is possible.

One thing to take care with user event is that, as far as I know, you can't manage the "buffer event". This can cause UI slowing done.

Regards

Link to comment
One thing to take care with user event is that, as far as I know, you can't manage the "buffer event". This can cause UI slowing done.

Wasn't thinking about that, but agree 100%. I usually use this in situations where the number of messages would be low/slow. I have not tried to pushed the limits of the approach.

Link to comment

I have not tried to pushed the limits of the approach.

I have smashed the Event Structure with events and it handles it really well (its easy to try it). Albeit this is usually with messages rather than data, but I have spoken to other devs that say they use it for streaming data between modules just fine.

For me the more importantly option is that you cannot manage the Event 'queue' as you can with the the Queue's 'queue' primitives (flush, check etc...).

Normally that is not an issue and and prefer to use Events, but it depends on the use case.

Link to comment

Speaking as the guy who wrote the queue primitives...

The queues are meant to be the primary means of communicating data in LabVIEW between parallel chunks of code. They are completely thread safe, and they participate with LabVIEW's concurrency scheduling algorithms. They're designed to minimize both data copies and latency and have been stable for many years.

User events go through queues that share most of the code with the general queues, although they have a bit more overhead since at any time there might be multiple listeners for an event, which can (not necessarily "will", just "can") cause more data copies. User events are data broadcasters, where as general queues are data point-to-point transmitters. The general queues thus have less overhead, but it is a very small amount less overhead.

For me personally, I prefer the general queues instead of the user events only because of the arcane nodes and special terminals that are required to register dynamic user events. I use user events when I need to have code that sleeps on both UI events and data arrival. But it is really personal preference -- many programmers are successful using user events generally.

Sweet summary. thumbup1.gif

Link to comment

Speaking as the guy who wrote the queue primitives...

The queues are meant to be the primary means of communicating data in LabVIEW between parallel chunks of code. They are completely thread safe, and they participate with LabVIEW's concurrency scheduling algorithms. They're designed to minimize both data copies and latency and have been stable for many years.

User events go through queues that share most of the code with the general queues, although they have a bit more overhead since at any time there might be multiple listeners for an event, which can (not necessarily "will", just "can") cause more data copies. User events are data broadcasters, where as general queues are data point-to-point transmitters. The general queues thus have less overhead, but it is a very small amount less overhead.

For me personally, I prefer the general queues instead of the user events only because of the arcane nodes and special terminals that are required to register dynamic user events. I use user events when I need to have code that sleeps on both UI events and data arrival. But it is really personal preference -- many programmers are successful using user events generally.

Hi

Very interesting! :thumbup1:

So... speaking to the guy who writed the primitives... what about the Notifiers Primitives?

I usually use them to send signal (like booleans to quits parallel While loops, o to send chuncks of data asynchronously to many consumers), but

now I'm working on an library that will use them to broadcast data to parallel tasks (using named notifiers)...

Any issues? On realtime targets?

Thanks

Bye!

Osvaldo

Link to comment

what about the Notifiers Primitives?

Notifiers also share code with the queues. Notifiers are broadcast, so there are data copies when using them because there could be other listeners at any time (listeners are formally registered for user events but not for notifiers, so a copy of the data is always retained in the notifier when it is read by a Wait node). Notifiers are essentially queues bound to a single element and always accessed with Preview Queue. Notifiers also have some "history of this message" code to track whether or not a given Wait node has seen a particular message.

Notifiers, because they make data copies, do have jitter on RT targets. But if you're not using them in a time critical loop, they do function just fine on RT targets.

All refnum functions in LabVIEW are, and must be, thread safe. Just forking a wire creates thread contention issues, and all refnum types must assume that they will be used concurrently in multiple parallel sections of code.

Link to comment

Notifiers also share code with the queues. Notifiers are broadcast, so there are data copies when using them because there could be other listeners at any time (listeners are formally registered for user events but not for notifiers, so a copy of the data is always retained in the notifier when it is read by a Wait node). Notifiers are essentially queues bound to a single element and always accessed with Preview Queue. Notifiers also have some "history of this message" code to track whether or not a given Wait node has seen a particular message.

Notifiers, because they make data copies, do have jitter on RT targets. But if you're not using them in a time critical loop, they do function just fine on RT targets.

All refnum functions in LabVIEW are, and must be, thread safe. Just forking a wire creates thread contention issues, and all refnum types must assume that they will be used concurrently in multiple parallel sections of code.

Ok!

Thankyou!:worshippy:

I use it like tag variables... I'm writing a library based on the idea of the NI CVT reference Library where the inner data storage based on Arrays where replaced on

a number of dinamically created notifiers, one for each tag defined... My hope is that each reading/writing operation on notifiers is decoupled by each other, so that

different loop can run in parallel so much as possible (the implementation of the original CVT reference library serialize all access on the AE that encapsulate the assary

it self...)

Ok... Ok... I could used the Shared Variables, but when the library development was started, no Shared Variable API was avaiable...

Have a nice day!

Osvaldo

Edited by osvaldo
Link to comment

For me personally, I prefer the general queues instead of the user events only because of the arcane nodes and special terminals that are required to register dynamic user events. I use user events when I need to have code that sleeps on both UI events and data arrival.

I've explored using user events for various things and eventually came to the same conclusion. Setting up user events is kind of a pain, so mostly I just use them to send messages to my fp event handling loop.

Has there been any discussion of revisiting user events and making them easier to work with?

Link to comment
Has there been any discussion of revisiting user events and making them easier to work with?
Yes, and it has been done. The current system is *after* we made them easier to work with. :shifty:

If you have any ideas, run them up the Idea Exchange, but keep in mind that some simplifications (like getting rid of the Register and Unregister nodes) aren't going to get very far because of the effect that has on performance. The current system gives LV clear signals about how long an event's data needs to be retained. Most other easier to program approaches leave LV with an open ended requirement to keep data around. (Note: This isn't my area of expertise and the preceeding explanation may be incorrect in some fashion.)

Link to comment

I've explored using user events for various things and eventually came to the same conclusion. Setting up user events is kind of a pain, so mostly I just use them to send messages to my fp event handling loop.

Has there been any discussion of revisiting user events and making them easier to work with?

I don't think they are any more painful than, say, queues or notifiers. My only gripe is that there aren't more built-in ones.(but that's something different).

Link to comment

I don't think they are any more painful than, say, queues or notifiers.

I agree. I use this architecture a lot:

I use user events when I need to have code that sleeps on both UI events and data arrival. But it is really personal preference -- many programmers are successful using user events generally.

So most of the time events are a more natural fit for me too (I have templates handle the registration etc... so its no real extra work to set up and handle)

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.