MaNGOSR2
Would you like to react to this message? Create an account in a few clicks or log in to continue.
MaNGOSR2

MangosR2 is a free, open source MMORPG framework, derived from MaNGOS project


You are not connected. Please login or register

MultiThread - Information and Problems

3 posters

Go down  Message [Page 1 of 1]

Reamer

Reamer

Hi,
Because Multithreadsystem is hard to understand I (and maybe some other) need some Informations

Basic informations are:
How many Thread and what Threads we have?
What is handle in each Thread?

Some Threadinformations

  • WorldThread(MainThread)

    • important method int Master::Run()
    • this thread starts a lot of other thread
    • in this the hole world are loaded in void World::SetInitialWorldSettings() (Startup) - also MapThreads are started here with
      Code:
          ///- Initialize MapManager
          sLog.outString( "Starting Map System" );
          sMapMgr.Initialize();
    • starts a listener socket


  • FreezeThread - This Thread check, if the WorldThread is in freeze
  • SoapThread

    • Config-option: SOAP.Enabled

  • Ra-Thread

    • Config-Option: Console.Enable

  • MapThread

    • the amound can control with MapUpdate.DynamicThreadsCount and MapUpdate.Threads
    • all Worldobjects update ticks from a specific maps are handle in one of this threads

  • some Network Threads
  • some Database Threads


How I unterstand Player actions?
Player loggin and lands on WorldSocket, now we create a new WorldSession
Code:

    // NOTE ATM the socket is single-threaded, have this in mind ...
    ACE_NEW_RETURN(m_Session, WorldSession(id, this, AccountTypes(security), expansion, mutetime, locale), -1);
Now we can put all incoming Client-Packets lands on WorldSocket to a specific WorldSession. (Note: Every Player has his own WorldSession). This code but ThreadSafe the Packet to m_Session.
Code:

m_Session->QueuePacket(new_pct);
Code:

/// Add an incoming packet to the queue
void WorldSession::QueuePacket(WorldPacket* new_packet)
{
    _recvQueue.add(new_packet);
}
Code:

ACE_Based::LockedQueue<WorldPacket*, ACE_Thread_Mutex> _recvQueue;
Every WorldSession Packets are handle in bool WorldSession::Update(PacketFilter& updater)
that function is called in void Map::Update(const uint32 &t_diff). Every Player has one WorldSession and the Map-Updater gets Session over the player.

In my eyes this looks good. Problems can accure with global stuff and dirty transports


Questions:
Where we have Thread crossovers? Where we handle global collections like Guilds, BG-joinLists?
I know we have database Thread. How are handle database threads? Why we need more then one?
I think the locking of the last objects like PetList, AggroList is totally wrong. This List should use by one thread (the specific map-thread)

I hope that someone can help. Please write only english, better long simply sentences as to short and hard to unterstand.

Reamer[code]



Last edited by Reamer on Tue Jul 10 2012, 14:29; edited 3 times in total

rsa

rsa
Admin

too many questions...
clean mangos have 6-8 threads (sorry, i'm forget this), related from config. all threads specialized:
- freeze detect
- world
- SOAP
- RA
- SQL Workers (some types)
- network workers.

In R2 WorldThread - (main, as your say) start some other threads (map workers). Any started threads (count - auto or from config)handle update all units/GO in map and also some player actions.
Player action handled in 3 points - on map worker immediately, on map worker separately, on world thread.
Database threads started from world thread (WorldRunnable::run) before starting world::update cycle
Most locking is wrong. But not all - most of locked containers currently must be used in not one map thread at one time... Need rewrite most container to exclusive-per-map architecture, but this architecture _must_ be multithreaded :) Don't need repeat original mangos fails.

Reamer

Reamer

rsa wrote:
Player action handled in 3 points - on map worker immediately, on map worker separately, on world thread.
Where are the split?

rsa wrote:
Most locking is wrong. But not all - most of locked containers currently must be used in not one map thread at one time... Need rewrite most container to exclusive-per-map architecture, but this architecture _must_ be multithreaded :) Don't need repeat original mangos fails.

Most datastores, like SpellStore, CreatureStore, can be share without problems, because we should have only read access-> This should make no multithread problems. The insertion of elements is only one time at WorldStart run in WorldThread.

Some other datastores like, BG-joinQueue, or LFG-Queue, should also handle in WorldThread + PlayerAction for delete insert should handle in WorldThread.

Other Queues like AggroList should handle only in specific MapThread.

Maybe you can show me where we have collisions.

rsa

rsa
Admin

mmm... for example - in planning make separate map servers. this require many parallel WorldThread's executing with asynchronous communications :)
main current problem - in current monstruous MapObjectStore. must be good rewrite his on simple container std::unordered_map<Object>, but...

rsa

rsa
Admin

Reamer wrote:
rsa wrote:
Player action handled in 3 points - on map worker immediately, on map worker separately, on world thread.
Where are the split?
need fully rewrite architecture on event-based. but more simple write new mangos anew :)

Reamer

Reamer

Why you want "many parallel WorldThread's", if we can't handle one. I think, it's better to make one WorldThread and a clean communication between Map-Thread to Map-Thread (maybe a player teleport from one map into an other) and Map-Thread to WorldThread (Chat, joining BG-Queue).

All global things should handle in WorldThread (like Guilds, BG-Queue), the other things should handle on Map-Thread (AggroList, Update from Gameobjects).

What you mean with "monstruous MapObjectStore"? Please give an example

rsa wrote:
Reamer wrote:
rsa wrote:
Player action handled in 3 points - on map worker immediately, on map worker separately, on world thread.
Where are the split?
need fully rewrite architecture on event-based. but more simple write new mangos anew :)
Thats no real answer.

EDIT: found something about OpcodePackets handling

Undergarun

Undergarun

Reamer wrote:I know we have database Thread. How are handle database threads? Why we need more then one?

I can answer why we need more than one database thread. I was helping Ambal to develop sync / async multiple threads for databases.

Every database thread opens one MySQL connection per thread. In database side, MySQL handles every incoming connection to new one MySQL Thread. On high loaded environments, too many queries are executed per second and are limited to máx per-cycle capacity on database server.

We have:
X asynchroniously connections + 1 Synchroniously connection for logon database.
X asynchroniously connections + 1 Synchroniously connection for characters database.
X asynchroniously connections + 1 Synchroniously connection for world database.
X asynchroniously connections + 1 Synchroniously connection for scriptdev database.

That means that MySQL can handle multiple threads running queries into DB Engine at the same time.

Also but i'm not sure, recommended config is 1 async and 1 sync connection per Map.Update thread. That means every Map thread can execute queries to db at the same time.

Reamer

Reamer

Maybe someone can explain, why every fifth Update step are only for NPCs

Mapupdate-Interval: 1000
in Screen german text -> english: "I'm in thread X"

MultiThread - Information and Problems Tlzld9xe

rsa

rsa
Admin

NPC's updated only if make someone/interchange with someone. if no - direct updated with interval 5*MapUpdate-interval (see MaNGOS::ObjectUpdater::Visit). This - last object update extension from mns (mr2083).

Sponsored content



Back to top  Message [Page 1 of 1]

Permissions in this forum:
You cannot reply to topics in this forum