This section addresses a number of thread management issues that you should be aware of in designing and programming a Message Queue C client. It covers the following topics:’
The Message Queue C-API library creates the threads needed to provide runtime support for a Message Queue C client. It uses NSPR (Netscape Portable Runtime) GLOBAL threads. NSPR GLOBAL threads are fully compatible with native threads on each supported platform. Message Queue C Runtime Thread Model shows the thread model that the NSPR GLOBAL threads map to on each platform. For more information on NSPR, please see
http://www.mozilla.org/projects/nspr/
Table 3–1 Thread Model for NSPR GLOBAL Threads
Platform |
Thread Model |
---|---|
Solaris |
pthreads |
Linux |
pthreads |
AIX |
pthreads |
Windows |
Win32 threads (from Microsoft Visual C++ runtime library msvcrt) |
Table 3–2 lists the handles (objects) used in a C client program and specifies which of these may be used concurrently and which can only be used by one logical thread at a time.
Table 3–2 Handles and Concurrency
Handle |
Supports Concurrent Use |
---|---|
MQDestinationHandle |
YES |
MQConnectionHandle |
YES |
MQSessionHandle |
NO |
MQProducerHandle |
NO |
MQConsumerHandle |
NO |
MQMessageHandle |
NO |
MQPropertiesHandle |
NO |
A session is a single-threaded context for producing and consuming messages. Multiple threads should not use the same session concurrently nor use the objects it creates concurrently. The only exception to this occurs during the orderly shutdown of the session or its connection when the client calls the MQCloseSession or the MQCloseConnection function. Follow these guidelines in designing your client:
If a client wants to have one thread producing messages and other threads consuming messages, the client should use a separate session for its producing thread.
Do not create an asynchronous message consumer while the connection is in started mode.
A session created with MQ_SESION_ASYNC_RECEIVE mode uses a single thread to run all its consumers’ MQMessageListenerFunc callback functions. Clients that want concurrent delivery should use multiple sessions.
Do not call the MQStopConnection, MQCloseSession , or the MQCloseConnection functions from a MQMessageListenerFunc callback function. (These calls will not return until delivery of messages has stopped.)
Call the MQFreeConnection function after MQCloseConnection and all of the application threads associated with a connection and its sessions, producers, and consumers have returned.
The Message Queue C runtime library provides one thread to a session in MQ_SESSION_ASYNC_RECEIVE mode for asynchronous message delivery to its consumers. When the connection is started, all its sessions that have created asynchronous consumers are dedicated to the thread of control that delivers messages. Client code should not use such a session from another thread of control. The only exception to this is the use of MQCloseSession and MQCloseConnection.
When a connection exception occurs, the Message Queue C library thread that is provided to the connection calls its MQConnectionExceptionListenerFunc callback if one exists. If an MQConnectionExceptionListenerFunc callback is used for multiple connections, it can potentially be called concurrently from different connection threads.
You should not call the MQCloseConnection function in an MQConnectionExceptionListenerFunc callback. Instead the callback function should notify another thread to call MQCloseConnection and return.