Except deadlocks have nothing to do with sharing memory, and everything to do with sharing state. Shared state is necessary whether your address space is shared or not, and deadlocks will always be a risk in complex systems, whether the components involved are in the same or different processes.
Anyway, I'm mostly a server-side engineer, so I can't speak well to the disastrous mess of GUI libraries and such, but the libraries I use are, indeed, thread-safe, and I'm quite confident that they will remain so. Their state is maintained through handles, not global variables.
I did a bunch of research for my PhD thesis on this, and came to the conclusion that "the probability of concurrency errors is proportional to the square of the amount of shared state". Threads share state by default, which brings significant risk.
Also server side engineers aren't necessarily safe; there are a number of C library functions that are not particularly reentrant. This has been known for decades because reentrancy is important in signal handling situations. The safest way of dealing with asynchronous signals, in fact, is to use global flag variables and use the flag as an indication that one should e.g. call waitpid because at least one SIGCHLD has come in since you last went through the main loop. You may deny that this happens particularly often, but that particular hack was an important simplification of my life a few months ago.
Anyway, I'm mostly a server-side engineer, so I can't speak well to the disastrous mess of GUI libraries and such, but the libraries I use are, indeed, thread-safe, and I'm quite confident that they will remain so. Their state is maintained through handles, not global variables.