Interprocess non blocking queue

Hi QNX Experts,

I am a new qnx user.
i have two kinds of processes running
process A:

thread A.1 send message by posix queue (non blocking) to thread A.2, and receive msg by posix q (non blocking) from threada A.2

thread A.2 receive message by posix queue (non blocking) from thread A.1, and also need to receive message from process B,C,D,E,F,G,etc in non blocking.
after receiving msg from B,C,D,E,F,G,etc, thread A.2 needs to forward the msg to thread A.1 (currently it is by posix queue mq_send)

process B: (and multiple of it)
send message to thread A.2, non blocking

process C:
send message to thread A.2, non blocking

process D:
send message to thread A.2, non blocking

process E:
send message to thread A.2, non blocking

process F:
send message to thread A.2, non blocking

process G:
send message to thread A.2, non blocking

how can i implement the IPC between process B…G and thread A.2?

regards

As a general rule, I think that queues should be used when required,
not just because they seem simpler to use because they are non-blocking.
This is not true however if you want the code portable to a non-QNX system.

Here is how I would design this.

Process A is a resource manager. The first thread that is started I’ll call A.2.
Any process can send a QNX message/pulse to this thread.
At startup, process A.2 creates anotherl thread A.1.
A.1 creates a special channel for the A.2 thread to send it a message.
A.2 knows about this channel because A.1 and A.2 share their data space.

When A.2 receives a QNX message from B,C,D,E,F, or, G, it replies immediately and then sends a QNX message to A.1.
Thread A.1 receives this message and immediately replies.
When A.1 wants to “send a message” back to A.2 it does it as follows.
If the message is small, it is just sent as the payload of a Pulse.
If the message is not small, A.1 sets up an in core FIFO queue, protected by a Mutex.
It then sends a Pulse to A.2 indicating that the FIFO is not empty.
When it receives the pulse, A.2 wakes up gains access to the mutex, and empties the FIFO.

No non-blocking Posix queue is needed.

Now let me anticpate an argument against this.
After process B-G sends a message to A.2, that process is blocked but I don’t want it to be.

This is mostly a missunderstanding and is not really correct. When B sends the message to A.2,
either B has higher priority or A.2 does.
If A.2 has a higher priority, then after the reply it will run.
If B has higher priority, then after the reply it will run.
If you happen to have SMP, then after the reply, both may run.

This is the same behavior as when using a Posix queue.

If you have multiple processors, and you are worried that two clients,
B and C for example might both try to send messages at the same time,
and that one might therefore be blocked waiting for A.2 to finish, you can implement A as a
multi-threaded resource manager.

The conditions under which this is not the right implementation are when B-G sporadically produce messages at a fast rate, but A.1 processes them slowly. In that case you could put a single Posix queue between
A.1 and A.2. An alternative would be to have A.1 put the messages in a FIFO, and have a third thread A.0 process the FIFO.

In all the years I have being doing QNX4 programs only once was I “forced” to used non-blocking messages.

That being said, if you must, take a a look at asynchronous messages.

Hi all,

thanks for all the feedback.

let me explain again,

Process B-G can be in send block after sending MsgSend

Thread A.2 must be able to receive, at anytime, message from A.1, B-G
message from A.1 maybe directed for B-G, and msg from B-G may be for A.1

is it possible (or allowed) to create two channel, one being for thread A.2 to B-G, and another one being for thread A.2 and A.1, if i can do that, i think, i can use send/rcv/reply in all the threads and processes…

currently im using name_attach in thread A.2 and name_open in process B to G.

when thread A.2 not in receive block, and a thread send it a msg, will be the msg be queued in the kernel?

my questions maybe irritating for the experts… :slight_smile:

Your description is not very well stated. When you say “Process B-G can be in send block after sending MsgSend” there
is a lot ambiguity. If you were an expert, you would know that “Send-Blocked” actually means that a thread has sent a message, but it has not been received yet. Since you are not an expert, I’m not sure if you understand this, or whether that was what you intended. I think you mean that B-G can send a message to A.2 and A.2 doesn’t have to reply right away. Is that correct?

Even this would be ambiguous. What do you mean by “can”? How does A.2 know whether to reply or not? Is A.2
waiting for a message from A.1 that will cause B-G to be replied to?

While you described the way you think you want this to work, you really haven’t told us what the data flow is. Maybe
if you did this, we could answer properly. So far it doesn’t even sound like you need two threads in A.

It is possible for a process to have more than one channel, but I don’t know what you want to do with them.
A channel is always a Receive channel, and the only threads you talk about that receive are A.1 and A.2 so it makes
no sense when you say “and another one being for thread A.2 and A.1”.

Finally, if A.2 is not received blocked, and a thread sends it a message, the sender becomes blocked waiting for
A.2 to go into receive mode. When it does, the message data is moved. You can think of that as being queued in the
kernel if you like, but the kernel does not have any message data buffers.

I might note that if A.2 has higher priority than the sender, it is unlikely that another process will be sending to it when it is not in receive mode. This is for two related reasons. 1) A.2 usually has a higher priority than the sender, so unless you are running in an SMP system, while A.2 is running, no lower priority process will run. 2) From your description, A.2 never blocks unless it is in receive mode.