Author |
Message
|
ydsk |
Posted: Mon Feb 26, 2007 4:00 pm Post subject: C++ MQ client - multi-threaded |
|
|
Chevalier
Joined: 23 May 2005 Posts: 410
|
Hi,
We are using MQ v5.3 client and server. The server is on AIX and multiple copies of clients should be on multiple Windows 2k / XP boxes ( a main C++ module which calls a C++ submodule, which in turn interacts with the MQ API).
I have a question on writing a multi-threaded C++ client application where in multiple clients on the same Windows machine do PUTs / GETs simultaneously to /from a pair of REQUEST / REPLY queues on the server.
A front-end user opens a customized GUI window to enter data in the fields to be sent to the REQUEST queue. Upto 10 such customized GUI windows can be opened at anytime on a single Windows box.I am thinking this should be handled by a multi-threaded sub-module which is called by a single main module ( I have been asked not to change the main module ).
A connection is made to the qmgr in the sub-module before the multi-threaded code and we get a hConn ( in C++ I know this is an object).
Can I use the same hConn in multiple threads running on a single Windows machine to do simultaneous PUTs/GETs through multiple threads ( each thread would use the same hConn but a different hObj for the same REQUEST queue ) ?
Or should I use a separate hConn and hObj for each thread to do a pair of PUT / GET ?
I kind of know that connection handles aren't thread safe but wanted to get some experts' advise on this forum.
Please advise.
Thanks.
ydsk. |
|
Back to top |
|
 |
jefflowrey |
Posted: Mon Feb 26, 2007 4:46 pm Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
You can't send multiple requests down a single client hConn.
You can, with the right options, make an hConn shareable across threads.
But you can only do one thing with that connection at a time. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
jsware |
Posted: Tue Feb 27, 2007 2:04 am Post subject: |
|
|
 Chevalier
Joined: 17 May 2001 Posts: 455
|
jefflowrey wrote: |
You can't send multiple requests down a single client hConn.
You can, with the right options, make an hConn shareable across threads.
But you can only do one thing with that connection at a time. |
Jefflowrey is indeed correct, but by "multiple requests" it means an MQPUT or MQGET is a "request". Thus you could share the connection handle across threads using the correct options and interleave MQPUTs and MQGETs. By this I mean that you do not have to do an MQGET to retrieve a response after its corresponding MQPUT.
You could create an internal worklist of things that need to get done. The GUI will add work items (MQPUT and MQGET requests) to this work list and the multi-threaded workers could process each work item. Since MQPUTs are typically very fast operations (they never have to wait), the workers could favour processing MQPUTs over MQGETs. Only when there are no MQPUTs outstanding would the workers sit waiting on any MQGETs.
This might be over-engineering this, and I have only spent 30 seconds thinking about it so you might want to think through your scenario further, but it could be an option... _________________ Regards
John
The pain of low quaility far outlasts the joy of low price. |
|
Back to top |
|
 |
ydsk |
Posted: Mon Mar 05, 2007 9:40 pm Post subject: |
|
|
Chevalier
Joined: 23 May 2005 Posts: 410
|
You mean in a single thread I can't use the same hConn to do a PUT first and then a GET ( say , put a request msg to a request queue and then after a few seconds do a get from a reply queue ) ??
The program in this link is doing it...
http://www-304.ibm.com/jct09002c/isv/tech/sample_code/mq/mqreq.cpp
Somebody pls explain how it works with a single thread vs multiple threads.
thanks.
ydsk. |
|
Back to top |
|
 |
jefflowrey |
Posted: Tue Mar 06, 2007 4:21 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
You can't do a PUT and a GET or two puts or two gets simultaneously from the same hConn.
Each call using an hConn has to complete before the next one can be attempted.
This causes some additional thinking to be done with multi-threaded programs. One approach is to have every thread use it's own hConn. Another approach is to use a connection pool and make sure that each hConn is only available to one thread at a time. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
jsware |
Posted: Tue Mar 06, 2007 6:18 am Post subject: |
|
|
 Chevalier
Joined: 17 May 2001 Posts: 455
|
ydsk wrote: |
You mean in a single thread I can't use the same hConn to do a PUT first and then a GET ( say , put a request msg to a request queue and then after a few seconds do a get from a reply queue ) ?? |
You can indeed perform an MQPUT and then when that has completed do an MQGET. In single threaded, your code effectively blocks (waits) until the call to MQGET completes. In multi-threading, two separate threads can issue their own MQAPI calls. You cannot however do the following:
Code: |
Thread1: -> MQPUT hConn
Thread2: -> MQGET hConn
Thread1: <- MQPUT
Thread2: <- MQGET |
Even if the connection handle is shared. You will get an MQRC_ return code indicating the handle is already in use when Thread2 issues the MQGET.
One way round this is for separate threads to maintain their own connection handles, queue handles etc. etc.
The connection handle (all MQ object handles) are shared resources and need appropriate synchronisation to enable everything to play nicely together. _________________ Regards
John
The pain of low quaility far outlasts the joy of low price. |
|
Back to top |
|
 |
ydsk |
Posted: Wed Mar 07, 2007 9:05 pm Post subject: |
|
|
Chevalier
Joined: 23 May 2005 Posts: 410
|
I think I almost got what you guys are saying.
I am planning to have 1 qmgr handle ( hConn) and 8 queue handles ( hObj) for the same request queue from 8 different threads all opening the queue one after the other but doing PUTs at different times.
Similarly 8 different hObjs for the same response queue to do GETs.
Each thread is likely to do multiple PUTs/GETs, of course not any 2 PUTs at the same time nor any 2 GETs at the same time.
All the 8 threads will keep the same request/response queue open through different hObjs but the same hConn. Is it possible ?
The question is can the same hConn be used by multiple threads ( for queue open calls) though PUTs/GETs happen at different times ?
Pls let me know.
thnx.
ydsk. |
|
Back to top |
|
 |
jefflowrey |
Posted: Thu Mar 08, 2007 5:29 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
Yes, if you ask for a thread-shareable hConn, you'll get a thread shareable hConn.
It's an option. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
ydsk |
Posted: Thu Mar 08, 2007 8:34 am Post subject: |
|
|
Chevalier
Joined: 23 May 2005 Posts: 410
|
Jeff,
I know a hConn but how do I ask for a thread-shareable hConn ? I mean , how do I specify it in the connect call/elsewhere ?
Pls suggest.
thanks.
ydsk. |
|
Back to top |
|
 |
jsware |
Posted: Fri Mar 09, 2007 12:12 am Post subject: |
|
|
 Chevalier
Joined: 17 May 2001 Posts: 455
|
ydsk wrote: |
Jeff,
I know a hConn but how do I ask for a thread-shareable hConn ? I mean , how do I specify it in the connect call/elsewhere ?
Pls suggest.
thanks.
ydsk. |
Have a look at the MQCONNX call arguments and the MQCNO structure. They allow you to request an MQCNO_HANDLE_SHARE* options. I think you will want MQCNO_HANDLE_SHARE_BLOCK which means that if one thread tried to issue an MQAPI call when another thread has one in progress, the thread issuing the call will block (wait) until the other thread has finished.
This might not be quite what you require if you have an MQGET with wait of say 30 seconds  _________________ Regards
John
The pain of low quaility far outlasts the joy of low price. |
|
Back to top |
|
 |
|