Quali lezioni hai appreso da un progetto che è quasi / effettivamente fallito a causa di un brutto multithreading?
A volte, il framework impone un certo modello di threading che rende le cose di un ordine di grandezza più difficili da ottenere.
Per quanto mi riguarda, devo ancora riprendermi dall'ultimo errore e sento che è meglio per me non lavorare su nulla che abbia a che fare con il multithreading in quel framework.
Ho scoperto che ero bravo nei problemi di multithreading che hanno una semplice fork / join e dove i dati viaggiano solo in una direzione (mentre i segnali possono viaggiare in una direzione circolare).
Non riesco a gestire la GUI in cui alcuni lavori possono essere eseguiti solo su un thread strettamente serializzato (il "thread principale") e altri lavori possono essere eseguiti solo su qualsiasi thread ma sul thread principale (i "thread di lavoro") ), e in cui i dati e i messaggi devono viaggiare in tutte le direzioni tra i componenti N (un grafico completamente connesso).
Nel momento in cui lasciai quel progetto per un altro, c'erano ovunque problemi di stallo. Ho saputo che 2-3 mesi dopo, diversi altri sviluppatori sono riusciti a risolvere tutti i problemi di deadlock, al punto che possono essere spediti ai clienti. Non sono mai riuscito a scoprire quella mancanza di conoscenza che mi manca.
Qualcosa sul progetto: il numero di ID di messaggio (i valori interi che descrivono il significato di un evento che può essere inviato nella coda di messaggi di un altro oggetto, indipendentemente dalla filettatura) vengono eseguiti in diverse migliaia. Anche stringhe univoche (messaggi degli utenti) si trovano a circa un migliaio.
Aggiunto
La migliore analogia che ho avuto da un altro team (estraneo ai miei progetti passati o presenti) era di "mettere i dati in un database". ("Database" che si riferisce alla centralizzazione e agli aggiornamenti atomici). In una GUI frammentata in più viste tutte in esecuzione sullo stesso "thread principale" e tutte le operazioni di sollevamento pesante non della GUI vengono eseguite nei singoli thread di lavoro, i dati dell'applicazione devono essere memorizzati in una singola plase che si comporta come un Database, e lasciare che il "Database" gestisca tutti gli "aggiornamenti atomici" che coinvolgono dipendenze di dati non banali. Tutte le altre parti della GUI gestiscono solo il disegno dello schermo e nient'altro. Le parti dell'interfaccia utente potrebbero memorizzare nella cache le cose e l'utente non se ne accorgerà se è scaduto da una frazione di secondo, se è progettato correttamente. Questo "database" è anche conosciuto come "il documento" nell'architettura Document-View. Purtroppo, no, la mia app memorizza tutti i dati nelle Visualizzazioni. Non so perché è stato così.
Partecipanti:
(i contributori non hanno bisogno di usare esempi reali / personali. Le lezioni da esempi aneddotici, se sono giudicate da te credibili, sono anche benvenute.)