Quando si crea una libreria per un programma semplice, cosa devo fare per proteggere gli altri dalla mancanza di sicurezza dei thread?

2

Quando si crea una libreria per un programma semplice, è più conveniente renderla protetta da thread o esiste un modo per rilevare l'uso del programma in un programma multithread e ASSERT () o determinare in altro modo (preferibilmente in fase di compilazione o di collegamento ) che potrebbe creare problemi.

L'aiuto correlato a questa domanda sarebbe il supporto automatico degli strumenti per la ricerca di potenziali problemi con la sicurezza del thread, la programmazione delle funzionalità del linguaggio che lo rafforzano,

    
posta DeveloperDon 14.09.2012 - 18:20
fonte

4 risposte

1

Dipende dal costo per renderlo thread-safe (in termini di tempo di sviluppo e impegno). Le cose da considerare includono:

  • Rendere sicuro un thread di libreria può essere difficile, in particolare quando si tratta di primitive di thread di basso livello, come le parole chiave% di Java synchronized e di lock di C #, quando l'efficienza o la velocità sono critiche.
  • Alcuni ambienti forniscono astrazioni di livello superiore come le Attendi e asincroni parole chiave . Usali se disponibili.
  • Utilizza classi di librerie thread-safe, come quelli in .Net System.Collections.Concurrent spazio dei nomi.
  • La sicurezza del thread potrebbe influire sulla portabilità del codice. Ad esempio, il codice C che utilizza i mutex pthread non funzionerà su Windows senza il supporto aggiuntivo della libreria.

Dipende anche da quanto probabile sarà utilizzata la libreria in un ambiente multi-thread e dalle convenzioni per la lingua utilizzata. Ad esempio, le istruzioni di progettazione di librerie di classi originali di Microsoft hanno dichiarato che i membri non statici necessitano non essere infallibile .

In ogni caso, l'approccio migliore è quello di documentare chiaramente cosa è e cosa non è sicuro da thread .

    
risposta data 19.09.2012 - 02:32
fonte
13

So I guess this is a vote for warning people using the library.

Sì, questo è esattamente ciò che il mio commento snarky è stato. A meno che non ci sia una buona ragione per aggiungere questa spesa, non farlo. La sicurezza del thread è costoso , per il progettista, per lo sviluppatore, per il tester e anche per l'utente che non ne ha bisogno. Sei colpevole di ottimizzazione prematura a meno che non ci sia una buona ragione per assorbire tali spese.

  • Un buon motivo: sei uno sviluppatore che lavora su una libreria di registrazione in cui un singolo elemento registrato può comprendere più righe nel file di registro e il registratore potrebbe essere chiamato da più thread. Il bisogno di sicurezza del filo è proprio lì nei requisiti, e questi requisiti hanno senso.
  • Cattiva ragione: dopo aver fatto così bene nella libreria di logging, ti sei reso responsabile del progetto che, tra le altre cose, svilupperà una libreria di numeri casuali. Qui le esigenze di guida sono correttezza numerica, facilità d'uso e velocità. Tu, capo del progetto, decidi di aggiungere la sicurezza del thread ai requisiti solo perché garantire la sicurezza dei thread è stato molto divertente nel progetto della libreria di log. Hai appena spazzato via il mio bisogno di velocità. Potrei fare trilioni di chiamate al PRNG durante una corsa notturna a Monte Carlo. La tua libreria mi è utile tanto quanto la funzione rand() integrata.

Costruisci la sicurezza dei thread perché ha senso e perché ce n'è bisogno, e anche in questo caso devi essere giudizioso su come procedere.

    
risposta data 14.09.2012 - 22:10
fonte
2

Qualcosa come questo (C #) FA il trucco ...

public class MyNonThreadSafeClass()
{
   public MyNonThreadSafeClass()
   {
       currentThreadId = Thread.CurrentThread.ManagedThreadId;
   }

   private readonly int currentThreadId;

   public void SomeNonThreadSafeMethod()
   {
      AssertSameThread();

      //do your thing   
   }

   private void AssertSameThread()
   {
      if(currentThreadId != Thread.CurrentThread.ManagedThreadId)
         throw new InvalidOperationException("Method must be called on the same thread that created the containing object");
   }
}

Ciò assicurerebbe che solo il thread che ha creato l'istanza dell'oggetto possa funzionare con esso. Variazioni di questo potrebbero garantire che nessun metodo venga chiamato contemporaneamente da thread diversi allo stesso tempo (ma consentire a un thread di creare l'istanza e quindi assegnarlo a un altro thread con cui lavorare) o che il thread di creazione debba avere un messaggio pump (ed è quindi un thread dell'interfaccia utente e quindi molto probabilmente il thread "principale" dell'app).

Tuttavia, nel complesso, se si prevede che la libreria possa essere utilizzata dai thread paralleli di un processo e si desidera supportarla, la renderei thread-safe. Non è poi così difficile; utilizzare monitor, mutex o altri blocchi per proteggere lo stato condiviso e favorire "funzioni pure" che non si basano sullo stato dell'ambito dell'istanza.

    
risposta data 14.09.2012 - 18:38
fonte
0

La cosa più importante che suggerirei è che una classe dovrebbe considerare nulli eventuali contratti con chiamanti che lo utilizzano in modo improprio, ma l'uso improprio da parte di un chiamante non dovrebbe influire sulla validità dei contratti con altri chiamanti.

Supponiamo, per esempio, che una classe implementa "Immunità da Popsicle" e promette che se IsFrozen restituisce true, tutte le successive osservazioni di una particolare proprietà produrranno lo stesso risultato. Supponiamo inoltre che un thread richiami il metodo "Freeze" di un'istanza mentre un altro thread sta modificando quell'istanza. I thread che modificano l'oggetto o chiamano Freeze non hanno aspettative legittime su ciò che l'oggetto potrebbe fare, ma codificano altrove che chiama IsFrozen , lo vedono restituito true , e osserva che altre proprietà dell'oggetto potrebbero avere il diritto di aspettarsi quest'ultima proprietà non cambierebbe mai; il fatto che i precedenti metodi abbiano abusato dell'oggetto non dovrebbe indebolire il diritto del secondo codice di aspettarsi che un oggetto che afferma di essere immutabile sia.

    
risposta data 15.07.2014 - 20:22
fonte

Leggi altre domande sui tag