You can adapt the receiving program to create a fifo (named pipe) with a well-known path name when it starts, and to remove that fifo when it exits. Typically, you have the receiver also open the same fifo for writing, which keeps it open: pipes without a writer tend to notify EOF to the readers.
Periodically, it can poll the fifo for data, without getting stuck waiting when there is none. I don't do C++, but in C you just mark the fifo O_NONBLOCK -- C++ will have some similar mechanism.
Any other process can then check if the fifo exists (so it knows there is an active reader), and send some text to it which the receiver will understand.
If you prefer threading to blocking, you can have a separate thread to read a blocking fifo, and do the synchronisation within the thread mechanism.
One issue with signals is that you need to identify the pid of the recipient. Using a fifo provides a stable naming method.
Edit: Prototyped a design solution that allows any number of clients to send messages to a server via a named pipe, with reliable startup and closedown conditions. Downside is, it's in Bash: client 40 lines, server 65 lines.