Threads, IO handling, and Event Queues

Nathan Yospe yospe at hawaii.edu
Mon Mar 10 09:14:12 CET 1997


On Mon, 10 Mar 1997, Carter T Shock wrote:

:I agree that multi-threading is not an issue to be taken lightly. I'd
:suggest that it only applies to the mud if you want to run different hunks
:of your world asynchronously. You could run different regions as seperate
:threads, unloading the threads when the region is devoid of players to
:reduce load. You could also run with each user as a seperate thread, but I
:wouldn't recommend it.

I have threads on my areas, rooms, and connections. From my programmer's
notes (yeah, I keep a notebook), this rather crude attempt at explaining
in english.

II]  - Threads & Processes
  A) Main Thread
    - read in all files
    - create the world
    - spawn a socket
    - wait for shutdown
  B) Socket Threads
    - wait for connection
    - spawn new socket
    - wait for input, output, or death 
    - page input to destination or
    - output output
  C) Global Thread
    - update clock
    - add new players
    - go to sleep for set amount of time
  D) Area Threads
    - if empty, wait for player
    - synch to global clock, if desired
    - launch all room threads
    - update area features (weather, etc)
    - place players into area
    - start sleep/update cycle
    - return all rooms to idle if players all leave
  E) Room Threads
    - if empty, sleep/loop cycle
    - wait for player
    - if player, go full animation
    - while events pending, execute events
    - while no pending, wait for event ripening or new event
    - ripen events on cycle
    - new events are generated by: AI, Player commands, Programs
III] - Combat

As you can see, the threads more than make up for themselves on a single
processor machine by localizing most of the computation to the players,
and only doing occasional (30 second) polls to unoccupied rooms to update
events. Areas without players are shut down altogether, their rooms'
threads frozen, etc. It does cause a brief pause when a player enters an
empty area... but that is a small price to pay. Areas do wait two seconds
to shutdown, just in case. When the MUD is totally empty, the only
activity is polling on the area threads and on the single waiting socket
thread. I suppose I could have the global thread freeze the area threads
too... Best of all, I don't have to worry about complex synchronization.
There is nothing lost in terms of simultanuity, because all global
activities are confined to the channel type functions, which don't go
through the thread heirarchy, instead depositing in each output buffer. I
know there are probably much better ways of doing this, but I am quite
proud of my performance in comparison to the old ROM engine I used.

:A shared memory solution has some interesting advantages over threads for
:handling players and such. Sure, shared memory (and processes that
:communicate via semaphores and such) is a cheap way to get threads. The
:main advantage to using shared memory segments to hold the mud's data is
:that you can attach any process to the memory segment. Consider:
:	- you can develop admin tools that attach to the mud process but don't 	 
:require you to log in as a "player"

Having already seperated player and character, and placed the player into
the socket thread, and the character into a room thread... the player is
sort of a user shell, with its own commands, including all imm commands
and creation commands.

:	- you can develop "builder" clients that allow your build crew to attach
:to 	  the mud and work, but don't allow interaction with the players (if
:yer 	  gonna build, BUILD, if yer gonna play, PLAY.)

Either is an option. Channels are open for those using the hands on
building method, and can be shut off for those using the method accessed
via the player shell. However, this seems independant of threads, at least
in my mind. What am I missing?

:One of the things I like about SillyMUD is the catastrophe code. The goblin
:raid on a town, the dwarf miner's revolt, etc. No reason you can't code up
:these "events" as a seperate process that runs, attaches to the mud, loads
:and tracks the appropriate critters, plays out its scenario and then cleans
:up after itself. In essence, if you design well, you should be able to
:dynamically modify what's going on in your world without having to reboot.

Ah, planned events. Yes, they are best done as a seperate process.. that
type of process is what I designed my internal programming language for,
originally. However, I made the process itself subject to the area
threads. It won't happen without witnesses... but if the witnesses are
late, they may find it well underway, or already over, leaving behind
corpses and damage. Its just... well, if there is noone there to hear it,
in my forest, the tree never falls... though it will be found on the
ground.

   __    _   __  _   _   ,  ,  , ,  
  /_  / / ) /_  /_) / ) /| /| / /\            First Light of a Nova Dawn
 /   / / \ /_  /_) / \ /-|/ |/ /_/            Final Night of a World Gone
Nathan F. Yospe - University of Hawaii Dept of Physics - yospe at hawaii.edu




More information about the mud-dev-archive mailing list