Diciamo che ho un server, dove i client che si connettono aggiornano costantemente il loro inventario.
Potrei semplicemente salvare le modifiche nel database dopo che un elemento è stato aggiornato, oppure potrei aggiornare l'intero inventario dopo che il client ha lasciato la sessione.
Se vado con il primo approccio, con le mie specifiche attuali, non posso elaborare tutti quelli allo stesso tempo. Se vado per il secondo, e la mia domanda per qualche motivo muore, gli aggiornamenti non vengono mai memorizzati nel database.
Che cosa posso fare per risolvere questo problema?
Posso solo trovare due soluzioni (entrambe implicherebbero checksum):
-
Avere un'applicazione secondaria in esecuzione, che crea semplicemente una memoria condivisa con nome. L'applicazione principale userà questa memoria per l'inventario di tutti i client, e se la mia applicazione muore, l'applicazione secondaria manterrà in vita la memoria condivisa, e quindi i dati, che possono essere salvati una volta riavviata l'applicazione principale.
-
Mappare ogni inventario client direttamente in un file univoco, come la memoria condivisa. Tuttavia, non rallenterà il mio programma? o è veloce come la memoria condivisa denominata? (Se ho capito bene, dovrebbe essere altrettanto veloce) ( questo è quello nella mia lista in questo momento ).
Per essere più specifici sul secondo approccio:
C'è una garanzia, almeno in Windows, che i seguenti 3 approcci saranno veloci tanto in scrittura / lettura? Se c'è QUALSIASI TIPO di ritardo , ho bisogno di sapere.
Per quanto ho capito, anche l'approccio per la mappatura dei file aggiornerà istantaneamente la memoria , ma non il file stesso (che va bene).
// normal memory accesss
int *normal_address = (int*)0x10203040;
*normal_address = 6; //write: 0.00002sec (for example)
int get_value = *normal_address; //read: 0.000001sec (for example)
// named shared memory
int *normal_address = (int*)0x10203040;
*normal_address = 6; //write: 0.00002sec (for example)
int get_value = *normal_address; //read: 0.000001sec (for example)
// memory mapped file
int *normal_address = (int*)0x10203040;
*normal_address = 6; //write: 0.00002sec (for example)
int get_value = *normal_address; //read: 0.000001sec (for example)
Note:
Entrambi gli approcci (file mappato in memoria e memoria condivisa denominata) utilizzano queste funzioni:
CreateFileMapping
OpenFileMapping
MapViewOfFile
-
L'applicazione principale verrebbe aggiornata quotidianamente, quindi potrebbe potenzialmente finire con un nullptr o qualcosa del genere. Il codice sorgente è un po 'vecchio e verrà aggiornato da più persone.
-
L'applicazione secondaria verrà creata una volta e mai aggiornata a meno che non sia necessaria. Quindi non c'è motivo di credere che se il codice è scritto bene, in futuro non dovrebbe esserci alcun bug per farlo andare in crash.
PENSIERI (ignora se necessario):
Forse l'applicazione secondaria potrebbe eseguire backup dei dati senza sincronizzazione: prima recuperare il checksum, quindi ottenere l'intero inventario. Se il checksum non corrisponde, prova a farlo di nuovo.
Forse un'altra alternativa sarebbe quella di rendere l'applicazione secondaria quella che effettivamente gestisce gli articoli.
- Ogni volta che un client aggiorna un articolo, l'aggiornamento verrebbe inviato direttamente alla seconda applicazione, che gestirà l'aggiornamento e quindi memorizzerà l'aggiornamento nel database una volta che il client sarà uscito. Poiché questa applicazione è veramente piccola e non cambierà, è molto semplice assicurarsi che non morirà. L'applicazione principale, tuttavia, cambierà costantemente, e questo è il motivo per cui può finire con un puntatore nullo che viene usato per errore o qualcosa di simile, e muore improvvisamente.