In Unix when you fork you usually wind up communicating
between the processes in a pipe. With threads the two
can communicate directly through an internal buffer (they share the same memory). With Unix you don't have to worry about how you use data, but there is more overhead. With threads you do have to be careful because the threads can trample over each other, but you can get better performance.
Where locking is necessary is when two things (threads,
processes, machines in a cluster, whatever) need to synchronize access to the same resource. Think here of Highlander - allow only one invocation at a time of an expensive CGI script, or also think of some CGI script that updates some user file. If your user submits twice you now have 2 processes, one of which might be reading while the other is deleting...
That is a race condition. If the first cleanly read, rewrote, and exited, you would be fine. The second likewise. If they collide...
It just happens to be really easy for two threads to collide. And much less common for programs to do it.