Ho un pool di thread con alcuni thread (ad esempio un numero di core) che funzionano su molti oggetti, ad esempio migliaia di oggetti. Normalmente darei a ciascun oggetto un mutex per proteggere l'accesso ai suoi interni, bloccarlo quando lavoro, quindi rilasciarlo. Quando due thread tentano di accedere allo stesso oggetto, uno dei thread deve attendere.Come sincronizzare l'accesso a molti oggetti
Ora voglio salvare alcune risorse ed essere scalabile, poiché potrebbero esserci migliaia di oggetti e ancora solo una mano piena di thread. Sto pensando a un design di classe in cui il thread ha una sorta di oggetto mutex o lock e assegna il blocco all'oggetto quando è necessario accedere all'oggetto. Ciò farebbe risparmiare risorse, poiché ho solo tanti oggetti di blocco quanti thread ho.
Ora arriva la parte di programmazione, in cui voglio trasferire questo disegno in codice, ma non so da dove iniziare. Sto programmando in C++ e voglio usare le classi Boost laddove possibile, ma le classi autoprodotte che gestiscono questi requisiti speciali sono ok. Come potrei implementarlo?
La mia prima idea era di avere un boost :: oggetto mutex per thread, e ogni oggetto ha un boost :: shared_ptr che inizialmente è unset (o NULL). Ora quando voglio accedere all'oggetto, lo blocco creando un oggetto scoped_lock e assegnandolo a shared_ptr. Quando shared_ptr è già impostato, attendo sul blocco corrente. Questa idea sembra un mucchio pieno di condizioni di gara, quindi l'ho quasi abbandonato. C'è un altro modo per realizzare questo design? Un modo completamente diverso?
Modifica: La descrizione precedente è un po 'astratta, quindi aggiungo un esempio specifico. Immagina un mondo virtuale con molti oggetti (pensa> 100.000). Gli utenti che si spostano nel mondo potrebbero spostarsi attraverso il mondo e modificare gli oggetti (ad esempio, sparare frecce ai mostri). Quando si utilizza solo un thread, sto bene con una coda di lavoro in cui le modifiche agli oggetti vengono accodate. Voglio un design più scalabile, però. Se sono disponibili 128 processori principali, voglio utilizzare tutti i 128, quindi utilizzare quel numero di thread, ciascuno con code di lavoro. Una soluzione sarebbe utilizzare la separazione spaziale, ad es. usa un lucchetto per un'area. Ciò potrebbe ridurre il numero di blocchi utilizzati, ma sono più interessato se esiste un design che consente di risparmiare il maggior numero di blocchi possibile.
Sembra che risolverà il problema. Poiché gli oggetti hanno un identificatore univoco, il pool di mutex ha un modo per identificare gli oggetti. Ci sto provando. Grazie! – vividos
Non è sufficiente spostare il problema su un livello? Ora abbiamo bisogno di un mutex sull'oggetto per assicurarci che sia sicuro assegnare un mutex all'oggetto. – stonemetal
No, hai solo bisogno di un mutex per proteggere il tuo pool di mutex (una mappa di ID oggetto per mutex in uso). – vividos