You can't trust that every signal sent will be delivered. For example, the linux kernel "coalesces" SIGCHLD if a process takes a long time in handling SIGCHLD from an exited child process.
To answer another part of your question, signals get "queued" inside the kernel if a number of different signals arrive in too short of an interval.
You should use
sigaction() to set up the signal handler with the
sa_sigaction member of
siginfo_t, setting the
sa_mask member of the
siginfo_t argument carefully. I think this means masking off all of the "asynch" signals at least. According to the man page for Linux
sigaction(), you'll also mask off the signal being handled. I think you should set the
sa_flags member to SA_SIGINFO, but I can't remember why I have this superstition. I believe this will get your process a signal handler that stays set with no race conditions, and one that doesn't get interrupted by most other signals.
Write your signal handler function very, very carefully. Basically just set a global variable to indicate that a signal got caught, and have the rest of the process deal with the desired action for that signal. Signals will be masked for the least amount of time that way.
Also, you'll want to test your signal handling code very thoroughly. Put it in a small test process and send as many SIGUSR1 and SIGUSR2 signals as possible, maybe from 2 or 3 special purpose signal-sending programs. Mix in some other signals as well, after you're confidant that your code can handle SIGUSR1 and SIGUSR2 swiftly and correctly. Prepare yourself for difficult debugging.
If you're using linux and only linux, you might think about using
signalfd() to create a file descriptor that you can
select() or poll to receive those signals. Using
signalfd() might make debugging easier.