While it's true that async-signal-safe programming bears some similarities to multi-threaded programming, an interrupt really isn't the same as a thread. Also, there's a lot more you can do in a signal handler than just set a flag: you can longjmp or even make calls to regular functions.
For example, one kind of program organization that used to be more common in Unix but that remains legal involves keeping signals masked all the time except around certain blocking system calls, e.g. ppoll, that atomically unblock signals and wait. In such a program, a signal can arrive only inside the blocking system call and so the handler can call regular functions without the usual strictures of asynchronous signal safety. (Consider responding to SIGWINCH, which tells you about changing terminal size.)
Synchronous signals are also special in that they're, well, synchronous. That means that in the signal handler you can examine the target memory address or instruction pointer and take action specific to a given spot in your program --- e.g. longjmp to an error handler.
All of this is useful, safe, and legal under POSIX. The main problems with POSIX signals are that, 1) as this thread underscores, most people don't understand them, and 2) signal handlers are process global and hard to share. (Consider if you're running two VMs in a process and each wants to use a SIGSEGV GC safe point trick.)
(userfaultfd, sadly, requires more system calls than a synchronous signal handler to handle anomalous memory access.)
We should be enhancing POSIX signals to make them easier to share, not casting aspersions on them.