Killing it with a signal other than SIGKILL, just causes a signal to be sent. This can be masked or ignored, but assuming it isn't (or after it's unmasked), then it interrupts the normal running of the program.
If an IPC-type system call is in progress (e.g. reading from a socket, select(), poll(), sleep() etc), then it will be interrupted and fail with EINTR in errno. A properly written application will re-issue the call after handling the signal.
The process then immediately executes a call to the signal handler, which may return to allow processing to continue, or it could call longjmp (in C), or it could exit the process, which is normally the default.
SIGKILL is completely different, none of the above happens. Instead it just quits the system call (which would presumably leave EINTR in errno, if the process was allowed to read it), then causes the task to exit immediately with no possibility to handle it.
But either of them I think waits for a "D" "uninterruptable sleep" state to finish. This would normally be something like a blocking disc read, page fault demand-load or something.