Identifying Threads Used by RTI Connext DDS Professional

 

Note: This article applies to Connext DDS Professional 4.x and above.

RTI Connext DDS Professional uses multiple internal threads for sending and receiving data, maintaining internal state, and calling user code when events occur. We recommend consulting the Connext User's Manual section Identifying Threads used by Connext. This solution duplicates some information from the User's Manual and explains how these threads can be identified in your system.

Threads used by Connext DDS Professional

A DomainParticipant always creates the following three threads:

  • Database Thread maintains the database of DDS Entities stored in the DomainParticipant. It is responsible for purging the objects marked for deletion when they are no longer needed.
  • Event Thread detects triggered events and acts accordingly, invoking user functions when needed (e.g., when a callback was specified for that specific event).
  • Receive Threads get bytes from transport plugins, then deserialize and store the (meta)data in the receive queue of a DataReader and invoke the  on_data_available() callback. Receive threads are also responsible for processing meta-data (e.g., discovery traffic, ACKs, NACKs).

The actual number of threads depends on the configuration of various QosPolicies as well as the implementation of the transports used by the DomainParticipant to send and receive data. In addition, other threads might be created for specific purposes:

  • Interface Tracking Thread checks if there is new interface data. It notifies the user/application and updates the interface data. Note: this thread is created in support of the IP Mobility feature introduced in 5.3.0.
  • Transport-specific Threads handle the tasks that are specific for a transport (e.g., the TCP Transport plugin creates two threads, one for control and one for events).
  • Asynchronous Publishing Threads handle the data transmission for Asynchronous Publishers.
  • Asynchronous Batch Flushing Threads handle batches of data samples, flushing them when needed. These threads are only created when batching is enabled (see BATCH QosPolicy (DDS Extension)) and  max_flush_delay is different than DURATION_INFINITE.
  • Topic Query Publication Threads publish historical samples in response to a TopicQuery. These threads are only created when topic query dispatch is enabled (see TOPIC_QUERY_DISPATCH_QosPolicy (DDS Extension)).

    Note: this thread is created in support of the Topic Query feature introduced in 5.3.0.

  • User Threads: in addition, your application may present threads that are not part of Connext DDS Professional. If those threads call a DDS API, Connext DDS Professional will automatically register them (allocate some resources to keep statistics and to handle concurrent access to DDS entities). To free up all the allocated resources, you may need to unregister these threads, as explained in this article from our Knowledge Base.

Further details regarding RTI Connext’s threading model can be found in the RTI Connext DDS Core Libraries User’s Manual (Connext DDS Threading Model section).

How to identify RTI Connext DDS Professional threads in your application

Checking the thread names from the call stack

In Connext DDS Professional 6.0.0 and previous versions, thread names are only available in a subset of architectures. This section lists the correspondence between RTI Connext DDS Professional threads and the functions they run. That way you can use this information to identify RTI Connext DDS Professional threads from the call stack, independently of your architecture. If you are using VxWorks or Integrity, please refer to the section “Checking the thread names at the OS level” below.

This is the correspondence between threads and the functions they run:

  • Database ThreadRTIEventActiveDatabaseThread_loop()
  • (Main) Event Thread: RTIEventActiveGeneratorThread_loop(). Note that this function is generic to all the event threads. That is, all of the event threads run RTIEventActiveGeneratorThread_loop(), which detects and handles events.  For this reason, it can be difficult to distinguish the Main Event Thread from other event threads (such as the Topic Query Publication Event Thread); however, to better make this distinction, you can check whether some (sub)functions are called (for example, the subfunctions related to the Asynchronous Batch Flushing Event Thread and Topic Query Publication Even Thread below).
  • Receive Thread: COMMENDActiveFacadeReceiver_loop(), which calls to a different function depending on what transport is being used to get the (meta)data:
    • Shared Memory: NDDS_Transport_Shmem_receive_rEA()
    • UDP: NDDS_Transport_UDP_receive_rEA()
    • TCP: NDDS_Transport_TCP_receive_rEA()
  • Interface Tracking Thread: RTIOsapiInterfaceTracker_()
  • Transport-Specific Threads:
    • TCP Control Thread: NDDS_Transport_TCPv4_Plugin_threadLoop()
    • TCP Event ThreadRTIEventActiveGeneratorThread_loop() and NDDS_Transport_TCPv4_Plugin_clientOn<event_name>()
  • Asynchronous Publishing Thread: RTIEventJobDispatcherThread_spawnedFnc()
  • Asynchronous Batch Flushing Event ThreadRTIEventActiveGeneratorThread_loop() and PRESPsWriter_onFlushBatch()
  • Topic Query Publication Event ThreadRTIEventActiveGeneratorThread_loop() and PRESPsService_onWriterServiceDispatchActiveTopicQueriesEvent()

As an example, if you are on GNU/Linux, you can run the following command on gdb to get the call stack:

(gdb) thread apply all backtrace

The same information can be seen with Visual Studio, too. To see this information in Visual Studio, you need to select Debug->Windows->Threads, and then do Ctrl+D, T. You will need to add a breakpoint and start the application in debug mode.

 Checking the thread names at the OS level

It is possible to check the internal name of RTI threads directly at the operating system level. In general, thread names follow this pattern:

 r<Module>[<Participant identifier>][<Thread index>][<Transport name>]<Task type>

 

For the full details of the above format, and example thread names, refer to this section of the User's Manual.

Checking the thread names using the Worker’s name

Connext uses the concept of a worker as an abstraction for threads. Workers are RTI-specific entities used internally to manage critical sections and to provide access to thread-specific storage. Most of the threads created by Connext have an associated worker. In addition, user threads calling certain APIs from Connext will have a worker associated with them. Workers are given a name when they are created. If you have the proper debug symbols, you can use the worker’s name to identify the thread (on a debugger, for instance).

For the full details of checking thread names using the Worker's name, refer to this section of the User's Manual.

Keywords:

Comments

thnks, Will try it today.