LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Communication between threads that are created with Invoke Method

Hello,

I'm making a program where I have many different threads that are created with Invoke Method
and I need to set up some type of communication between these threads. I would like to have
comments from more experienced LV programmers which is the best way to go.

For now, I am considering the following possibilities

1. Notifiers. With this I'm not sure if this is useful for me, since in the help it says that data can be
received from another section of the block diagram or from another VI running in the same application
instance. In my case, are the VIs in the same application instance? Also can one thread wait for
notifications from number of other threads?

2. Queues. This one seems the best choice, but I can not confirm this without using it. If I understood
correctly a queue can be shared by multiple threads. I need atleast the ability for one thread to read
and several others to write to queue. If possible several writers and readers would be even better.
With the use of Preview Queue Element, a thread can determine if the message is for it or not.

3. Global variables and semaphores. This could lead to a messy code, since I will need to have a lot
of threads and every communication line needs new global variable and semaphore.

If you have some solution that is even better, please share it.

Thanks.
0 Kudos
Message 1 of 9
(3,080 Views)

Make the VI that you invoke have a queue as an input and create the thread at the envoke method and pass it to the vi.  Now you have a queue on the invoker that is shared with the concurrent vi.  Queues have the most flexability of the synchronization object in my opinion.

Paul

Paul Falkenstein
Coleman Technologies Inc.
CLA, CPI, AIA-Vision
Labview 4.0- 2013, RT, Vision, FPGA
0 Kudos
Message 2 of 9
(3,070 Views)
Thank you Paul for your reply.

So, you mean that I can have one queue for to be used by all the threads? Everyone
can read and write into the same queue? To read a message in the queue I would
need to poll for the queue constantly. With notifiers I don't need to poll. This would make
the program use less resources and be more real time. Should I combine these two,
to get the rid of the polling?

For notification, do I need to make a different communication line for each threads, or
do notifications work like a bus, as in ethernet, every notification is sent to every thread
and the thread only reacts on the notifications that it has registered.

The communication line won't propably be very busy and the threads are mostly doing
DAQ card operations.
0 Kudos
Message 3 of 9
(3,064 Views)
Hello,

I've been using user events for several years now (still evolving) to communicate between dynamically started modules of my applications.

The events are created, send and destroyed in a sub VI and the data type is always a cluster with an enum (for event type) and a variant (for any kind of data). The enum value selects the data conversion.

Using one defintion for all communication can have a drawback on performance (circling events back and forth), but creating multiple events (refnums), one for each unique communication path eliminates this problem. By using all type defs events can easily be added.

Important the sender of an event should not be a receiver for that event.

Its a one to many, many to one and many to many architecture.

The event structure handles the queueing of events (you will never miss one and no polling), only prevent that events are handled faster than they are created.

FOR NI: It could be very usefull to me that the event queue of the event structure can be flushed like the qeueuing functions. Maybe something for the next version, or if already possible please tell me how.

Regards,

André
Regards,
André (CLA, CLED)
0 Kudos
Message 4 of 9
(3,051 Views)

I would also would give the queue a try.... if you have always only one reader.

I use the functional global (LV2-style global)  to 'publish' the data and queues/notifyer to tell the others...  but this also depends on the amout of data you want to spread around.

Maybe in the newer versions there is a adequate replacement for functional globals, but I don't had the time to test these 'replacements'.... (And to follow altenbach, the functional global is very flexible Smiley Wink )

Greetings from Germany
Henrik

LV since v3.1

“ground” is a convenient fantasy

'˙˙˙˙uıɐƃɐ lɐıp puɐ °06 ǝuoɥd ɹnoʎ uɹnʇ ǝsɐǝld 'ʎɹɐuıƃɐɯı sı pǝlɐıp ǝʌɐɥ noʎ ɹǝqɯnu ǝɥʇ'


0 Kudos
Message 5 of 9
(3,048 Views)
I use named queues for inter-thread communications (sometimes).
 
Jim Krings design pattern " Queued Message Handler with Response Notification" is a good place to start.
 
Ben
Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 6 of 9
(3,044 Views)
Thank you all for your replies. I will look into all those possibilities more closely and
get back to this topic when I have further questions.
0 Kudos
Message 7 of 9
(3,032 Views)
With the use of Preview Queue Element, a thread can determine if the message is for it or not.

You can create a single queue with a cluster data type consisting of an enum (message type) and a variant (data); in fact this is a common technique. The technique you've described of using Preview Queue Element may affect your performance considerably. All of your threads will be effectively polling and only run as fast as the slowest thread.  For example; if your messages contain 10 Hz, 20 Hz and 100 Hz data that are identified by an enum (data type); your 20 and 100 Hz threads will block waiting for the next 10 Hz element to be pulled from the queue by the 10 Hz thread. Queues by default are unbounded and in this scenario you might probably run out of memory and crash your app.

If your architecture consists of a single channel for data (a TCP/IP connection for example) and you will receive various types of messages over that channel, write an intermediate VI that pulls data from that channel and then directs it to the appropriate handling thread via a dedicated queue. The intermediate VI pulls the data from the data channel, reads the data type portion of the message and then enqueues the data. The servicing threads don't have to evaluate the data type, they each simply run as fast as they can and never blocks on data they doesn't evaluate...Smiley Happy




Message Edited by Phillip Brooks on 08-20-2007 11:45 AM


Now is the right time to use %^<%Y-%m-%dT%H:%M:%S%3uZ>T
If you don't hate time zones, you're not a real programmer.

"You are what you don't automate"
Inplaceness is synonymous with insidiousness

0 Kudos
Message 8 of 9
(3,028 Views)

I usually use one named queue for each thread I create as a message reciever.   Each theade has a state which is check  for messages which will process messages.  If you want the messages to have a blocking (synchronous) call a notification back to the caller is required.  This can get complex but does work well.

 

Paul

Paul Falkenstein
Coleman Technologies Inc.
CLA, CPI, AIA-Vision
Labview 4.0- 2013, RT, Vision, FPGA
0 Kudos
Message 9 of 9
(3,017 Views)