Sorry about thread necromancy, but this problem is my FAVORITE pet-project for learning and teaching concurrency models and frameworks!
Running every client/mob in their own thread does give a natural division, but as several have noted threads are expensive when you use more of them than you have CPU cores. If this isn't a compelling reason not to use it in your MUD, it's still a good reason to learn a better way.
Running all clients in a single fixed-time game-loop, with actions taking some number of loops, is a familiar method from the world of graphical games. It does bind everything in the world to the same time-cycle, although making the loops sufficiently fine-grained can mask that. The main drawback of this method, as I see it, is that it is not inherently parallelizable. Someone noted that you can create threads to offload constructing/parsing/transceiving I/O, running AI and so on to other threads, but getting the main game logic parallelized requires a fundamental change and a lot of work to keep things thread-safe.
If you did all of that work, you'd probably end up with something akin to my current favorite, the Actor model (http://en.wikipedia.org/wiki/Actor_model). The Actor model is a time-sharing strategy that ends up working out pretty close to what you were proposing with the one-thread-per-client idea. Using it, you code your "Actors" like they're standalone threads, with a few restrictions: they must be event-driven, and they can only communicate with the rest of the system by passing messages (which is different but simple). The event-driven bit makes room for your truly-independent-timing, by scheduling Actor-specific events to fire at particular times, e.g. when an action is completed or at some client-specific frequency.
Under the hood the implementation uses a queue (or queues) of messages being generated by all the actors, and a pool of threads matching your # of CPU cores. The threads pull messages off of the queues and the invoke the recipient Actor's message-handling methods to handle them, running in the context of that Actor until the message is "handled". From your point of view, each Actor gets its very own thread whenever it is actually running, but from the system's point of view there are only as many threads as there are CPUs to run them.
There are some great Actor frameworks out there, namely Erlang/OTP and Akka, but the basic idea is simple enough that you could implement it in any language without the additional fuss of a framework.
For completeness, the Actor model is really just the combination of message-passing for thread safety, event-driven programming for concurrency, and a thread dispatching mechanism. If you were to remove the thread-dispatch bits, you'd be left with a "reactive" system, which is very in vogue for scalability in general right now (see http://www.reactivemanifesto.org/). You could then map execution to multiple machines in a cloud or whatever... you get the idea... which is all to say that your MUD programming project may be teaching you marketable programming skills. Hooray!