c++ - Sending list of connected users to newly connected user in multithreaded iocp server -


i need advice how send doubly linked list of connected users. basic information code , approach far:

i keep information connected users in doubly linked list, shared among threads. store head of list in global variable : *pper_user g_userslist, , struct users like:

typedef struct _user {   char      id;   char      status;   struct _user  *pctxtback;    struct _user  *pctxtforward; } user, *pper_user; 

when new user connects server, data connected users gathered linked list , send him:

 wsabuf wsabuf; pper_player ptemp1, ptemp2; unsigned int c=0;  .....  entercriticalsection(&g_csuserslist);   ptemp1 = g_userslist;   while( ptemp1 ) {    ptemp2 = ptemp1->pctxtback;    wsabuf.buf[c++]=ptemp1->id;     // fill buffer data users    wsabuf.buf[c++]=ptemp1->status; //    ptemp1 = ptemp2;    };  wsasend(...,wsabuf,...);  leavecriticalsection(&g_csuserslist); 

but few things code above makes me confused:

  1. the linked list rather under heavily usage other threads. more connected users (for example 100,1000), longer period of time list locked entire duration of ghatering data. should reconcile or find better way this?

  2. it seems when 1 thread locks list whilst while loop went trough chained struct(users) gathering id, status , other threads should use same criticalsection(&g_csuserslist) when users want change own id, status etc. kill performance. maybe should change design of app or something?

any insight may have appreciated. in advance.

the problem see in code (and more in description of app) size of critical section protects g_userslist. rule avoid time consuming operation while in critical section.

so must protect :

  • adding new user
  • removing user @ deconnexion
  • taking snapshot of list further processing

all operation memory only, unless go under heavy conditions, should fine provided put io outside of critical sections (1), because happens when users connecting/disconnecting. if put wsasend outside of critical section, should go fine , imho enough.

edit per comment :

your struct user reasonably small, between 10 , 18 useful bytes (depending on pointer size 4 or 8 bytes), , total of 12 of 24 bytes including padding. 1000 connected users have copy less 24k bytes of memory , having test if next user null (or @ keep current number of connected user have simpler loop). anyway, maintaining such buffer should done in critical section. imho until have far more 1000 users (between 10k , 100k, other problems ...) simple global lock (like critical section) around whole double linked list of user should enough. needs probed because may depend of external things hardware ...


too long don't read discussion :

as describe application, gather list of connected users when new users connects, have 1 full read per 2 writes (one @ connection , 1 @ deconnection) : imho no use trying implement share locks reading , exclusive ones writing. if did many reads between connection , deconnection, won't same thing, , should try allow concurrent reads.

if find contention heavy, because have large number of connected users , frequent connection/disconnection, try implement row level like locking. instead of locking whole list, lock processing : top , first insertion, current record plus previous , next deletion, , current , next while reading. hard write , test, more time consuming, because have many lock/release while reading list, , have cautious avoid dead lock condition. advice don't unless required.


(1) in code show, wsasend(...,wsabuf,...); inside critical section when should outside. write instead :

... leavecriticalsection(&g_csuserslist); wsasend(...,wsabuf,...); 

Comments

Popular posts from this blog

javascript - how to protect a flash video from refresh? -

visual studio 2010 - Connect to informix database windows form application -

android - Associate same looper with different threads -