Esempi di scenari iterativi concomitanti necessari

1

Sto cercando di avvolgere la mia mente su diverse soluzioni di concorrenza per diversi thread che si ripetono sulla stessa collezione, ma ho difficoltà a trovare scenari di buon realismo (ma preferibilmente di facile modellazione) per codificare. Sto cercando scenari realistici per:

  1. Uno scenario in cui più thread possono scorrere simultaneamente su una raccolta e bloccare ogni elemento così come viene fornito e apportare alcune modifiche, gli elementi non possono essere visibili in uno stato parzialmente aggiornato
  2. Uno scenario in cui thread diversi tentano di scorrere su una raccolta, ma solo uno alla volta dovrebbe essere consentito a
  3. Uno scenario in cui diversi thread possono scorrere su una raccolta per la lettura, ma solo un thread può scorrere per scrivere

Qualsiasi altro scenario di iterazione concorrente con cui potresti venire in mente sono i benvenuti :) grazie!

    
posta Homde 06.04.2011 - 21:36
fonte

5 risposte

1

Non sono sicuro della necessità di trovare scenari del mondo reale.

Perché non scrivere semplicemente il codice con questi vincoli dove stanno cercando di ottenere l'accesso a un oggetto nullo effettivamente vuoto. Ciò elimina la necessità di risolvere il problema del dominio allo stesso tempo.

Aggiungi un fattore tempo variabile all'atto di "toccare" l'oggetto nullo per aggiungere qualche variazione - e osserva il conflitto andare e attivare e disattivare il numero di thread e oggetti di contenuto.

Quindi registra tutte le collisioni che si verificano - che, si spera, avresti ben protetto, oppure guardalo in stallo e trascina i tuoi registri per individuare dove si è verificato il deadlock.

    
risposta data 06.04.2011 - 22:03
fonte
1

Le raccolte presentano problemi di concorrenza specifici. Sono uno sviluppatore .net, ma posso descrivere i problemi in termini abbastanza generali, credo.

Internamente la collezione potrebbe essere implementata in diversi modi. Supponiamo che sia solo una lista collegata.

La raccolta può supportare un numero di operazioni. Aggiungi ed elimina, elimina [indice] e inserisci. Permette anche di iterare sulla collezione.

Quindi hai accesso simultaneo. Ecco alcune situazioni da considerare.

Stai iterando sull'intera collezione. Stai facendo qualcosa di simile (pseudo codice)

per count = 1 per collection.count    fare qualcosa successivo

Per il gusto di quanto segue, conta attualmente = 5 e collection.count = 10.

Mentre lo fai, fai una delle seguenti azioni. Esegui individualmente ogni scenario:

1) Aggiungi un elemento alla raccolta. Questo probabilmente funzionerà finché il comportamento è quello di inserire l'elemento alla fine.

2) Inserisci un elemento nella posizione 3 Non male, il conteggio sale di uno, però il nuovo oggetto non sarà incluso nella nostra iterazione.

3) Elimina un elemento nella posizione 3 Ok, ora abbiamo problemi. Count è ora 9 (ricorda che ogni scenario da solo, 1) e 2) non è successo in questo caso). la nostra posizione attuale è ancora 5, ma poiché 3 è stata rimossa, la lista si è spostata a sinistra, ora saltiamo un elemento perché l'elemento 6 è ora l'elemento 5 e stiamo già leggendo 5. Ma peggiora !!! Immagina le tue cose che stai facendo con l'articolo 5 sta leggendo i membri dell'oggetto nella posizione 5 in base al suo indice.

thread 1 - > collection [5] .element1 = 10 thread 2 - > elimina l'elemento 3 thread 1 - > collection [5] .element2 = 10

in questo momento abbiamo impostato due elementi su diversi elementi.

È ancora peggio nel prossimo.

4) elimina l'elemento 5 mentre si trova attualmente sull'elemento 5. Sì, rimuovi l'elemento, forse chiama il suo metodo "Dispose" mentre lo rimuovi, ma lo stai ancora trattando come membro attivo della raccolta su un altro thread.

Questo è un caso semplice. Spero che ti dia qualche idea.

    
risposta data 06.04.2011 - 23:43
fonte
0

Se stai cercando esempi concreti, uno scenario che utilizzerei è un semplice elenco di elementi, ad esempio il database preferito "Prodotti". Avete un reparto merci interno che aggiunge prodotti a volte e cambia spesso la quantità di un prodotto. Hai un reparto merci esterno che spesso modifica la quantità di un prodotto ma non aggiunge o rimuove mai prodotti. Hai un manager che aggiunge, cancella, rinomina, modifica quantità e rapporti sui prodotti. E hai un team di stock in tempo reale che aggiunge, rimuove e modifica le quantità.

Questo copre le azioni CRUD comuni e facilita la generazione di casi d'uso. Se la tua raccolta è anche ordinata potresti aggiungere la posizione a quanto sopra e ordinare da quella (e usare semplicemente un'altra proprietà di interi per quello per renderla semplice). Continuo a sottolineare l'ordinamento perché quel rapido ciclo di rimozione è difficile da testare.

    
risposta data 07.04.2011 - 01:03
fonte
0

(1) sarebbe un naiive approccio orientato agli oggetti per mantenere una collezione di oggetti in movimento in una simulazione di tipi che deve essere resa visibile ad altri thread: il "simulatore" dovrebbe blocca, non solo la sua lista (per evitare il taglio), ma anche ogni "oggetto" che sta aggiornando.

Realisticamente, lo farei per qualcosa di simile a un pathfinder: Blocca la raccolta degli agenti per evitare di affettare e iterare su tutti gli agenti, inserendoli in una "coda dei lavori" (i puntatori della coda sarebbero riservati solo a questo scopo, quindi no l'altro thread lo vedrebbe).

Quindi, usando OpenMP o qualcosa di simile, avrei ogni thread di lavoro bloccare rapidamente la coda, escludere un agente da esso, quindi sbloccare la coda (o usare una coda [quasi] bloccata]. Ogni thread di lavoro blocca il suo agente prima di aggiornarlo.

La mia risposta per (1) potrebbe anche essere applicata a (2) : il "simulatore" e qualunque cosa mantenga la collezione di agenti sono davvero le uniche cose che dovrebbero essere permesso di scorrere l'intera lista (e desiderabilmente farlo in un thread alla volta, o solo un periodo di thread).

Un examaple per (3) sarebbe una tabella di stringhe: più thread possono ottenere un blocco condiviso per cercare le stringhe esistenti e solo un thread alla volta può aggiungere una stringa alla tabella.

    
risposta data 24.07.2012 - 05:09
fonte
0

Un esempio che ho scoperto in un posto di lavoro precedente:

Un pezzo di codice aveva una collezione di buffer di frame che venivano aggiornati da più thread. I thread erano:

  • Un thread che ha ricevuto frame dalla rete, li ha elaborati e aggiornato il buffer in questione. (Operazione di scrittura)
  • Un thread che ha convertito i frame in pixel per la visualizzazione (operazione di lettura)
  • Un'altra parte di codice che ha mantenuto lo stato della connessione della rete e ha sostituito il buffer con il testo "Connessione persa". (Operazione di scrittura)

Questi frame buffer non erano sincronizzati correttamente. Sono riuscito a scoprire che il thread di lettura stava iterando i frame buffer e li spingeva al codice nativo, quando il thread 3 è arrivato e ha causato l'arresto dell'intera app.

In questo caso, la lettura e la scrittura dovevano diventare esclusive (lo scenario 2).

    
risposta data 24.07.2012 - 10:30
fonte

Leggi altre domande sui tag