A signal handler is just a function within a given process' address space. This function is executed whenever the signal is received. There's nothing special about it (although there are certain actions that should not be performed within a signal handler), and it does not reside in a special thread.
While signals are often described as being software interrupts, they aren't actually asynchronous.* When a signal is sent to a process, the kernel adds it to the process' pending signal set. It doesn't cause anything to happen immediately. The signal will only actually do anything at the next context switch back to userspace (whether that's a syscall returning or the scheduler switching to that process). If a process were to, for whatever reason, never switch from kernel to user, the signal would be kept in the pending signal set and never acted upon.†
When a process establishes a signal handler, it gives the kernel an address to a function. When the process is to receive a signal, the next context switch from kernelspace to userspace will not restore the execution context from before the process entered the kernel (usually, the context is saved when entering the kernel and restored upon exiting it). Instead, it will "restore" execution at the location of the signal handler. When the signal handler returns, it executes code which calls rt_sigreturn(), which restores the real execution context, allowing the process to continue where it left off.
When a process has multiple threads (i.e. there are multiple processes in a given thread group), the signal is sent to one of the threads in the thread group at random. This is because threads typically share memory and many other resources and run the same code.
* While they aren't asynchronous from the perspective of hardware, they are effectively asynchronous as far as userspace applications are concerned. This is why they are sometimes called software interrupts.
† When I refer to context switches, I mean privilege or process switches (i.e. both simple mode transitions between kernel and user within the same process and "true" context switches between processes or kernel threads).