- if you need to transfer data
- Have the server dedicate a thread to receive and immediately reply messages, minimizing the blocking interval.
- Have the client send the data via a thrad
- Use POSIX message queue
- If you don’t need to transfer data
- Posix signal
- SIGEV_PULSE_INIT(&event, coid, priority, pulse_code, pulse_value);
- If you want the thread that receives the pulse to run at the initial priority of the process, set priority to SIGEV_PULSE_PRIO_INHERIT.
- Int MsgSendPulse(coid, priority, pulse_code, pulse_value)
- Int MsgRecivePulse(chid, &pulse, sizeof(pulse), struct _msg_info *info); // info should be NULL for pulse.
- Int MsgReceive(chi, &msg, bytes, struct _msg_info *info); // a return of “0” means a pulse is received; if >0, a normal message.
Priority Inversion: a low-piority thread consumes all available CPU time, even though a higher-priroity thread is ready to run.
To avoid it, the solution is Priority inheritance, or Message-driven priority: A server process receives messages & pulses in priority order. the receiving thread within the server process inherits the priority of the sender thread; when it receives messages (for pulses, receiving thread will run at the priority of the pulse).
Assume there are 3 threads, t1 (priority 13), t2 (priority 10), server thread (priority 22),
- If the sender(t2) is of lower priority (10) than the receiver (22), the effective priority of the server thread changes when the message is received (on MsgReceive).
- the sender(t2)’s work is done at priority 10.
- If another higher priority thread(t1) is running when t2 calls MsgSend(), it will not preempted by t2.
- If the sender(t1) is of higher priority(13) than the receiver(10), the effective priority of the server thread changes on MsgSend().
- If multiple clients are SEND blocked, server will inherit the priority the higher client.
- After the server reply to t1 and t2, its priority will still be 13, and receive blocked.
- Priority inheritance can be turned off by channel flag _NTO_CHF_FIXED_PRIORITY. If the channel is created with _NTO_CHF_FIXED_PRIORITY, receiving threads won’t change priorities to those of the sending threads (does it work for pulses???)
- For pulses (an example of pulse priority)
- Pulse have a priority value while being initialized. If you want the thread that receives the pulse to run at the initial priority of the process, set sigev_priority to SIGEV_PULSE_PRIO_INHERIT (note: not the priority of the thread which sends the pulse, but the initial priority of the process!???)
- Sender can specify the priority of the pulse, or –1 to use the priority of the calling thread.