Refactor signal handling to use a pipe

This commit removes the need to poll a global array for received signals every
second by introducing an internal pipe(2).

The writing end of the pipe is being used in the block trapping the signals.
Whenever a signal is received, the signal's name gets written to the pipe.

Instead of polling for received signals, the code now uses select(2) to
check whether the internal pipe has been written to and can be read from.
select(2) is blocking until one of the passed file descriptors is ready for
reading/writing or has an exception, which means the code does not need to use
`sleep 1` anymore.

So when a signal is sent to the sidekiq process, the signal name gets written to
the internal pipe, select(2) returns and the process can react according to the
received signal. After handling a signal, select(2) gets called again and blocks
until receiving another signal.