Yeah, you could use futexes, if you didn't mind being totally nonportable off Linux.
A more portable approach with essentially no downsides is to pass the fd of a pipe to your recipient process, and use its blocking behaviour when empty to implement your semaphore.