2012-06-02 22 views
8

Vorrei sapere se DWScript è in grado di utilizzare i thread all'interno degli script, poiché alcuni motori non sincronizzano l'accesso alle sue strutture di dati interne.DWScript è sicuro per i thread?

+0

-1 Questa domanda è banalmente risolta leggendo la documentazione, la prima pagina del sito Web del progetto DWScript, la ricerca sul Web, ecc. Fare qualche sforzo prima di porre la domanda. –

+1

Se la risposta è così facile da trovare, allora deve sicuramente averlo saltato più volte, altrimenti non avrei postato la domanda. – FHannes

+4

@david: se tutti avessero solo rtfm, non ci sarebbe stackoverflow :) –

risposta

4

Arnaud diede i punti chiave:

  • ogni istanza compilatore può essere richiamato da un solo filo per volta. È possibile avere più istanze del compilatore richiamate in più thread contemporaneamente e una particolare istanza del compilatore può essere utilizzata da più thread, purché solo un thread la utilizzi per volta.
  • ogni programma compilato può avere più esecuzioni, ogni esecuzione può essere eseguita nella propria thread. Inoltre una particolare esecuzione può essere utilizzata da più thread, purché solo un thread lo usi alla volta.
  • Ogni esecuzione ha il proprio spazio per le sue variabili, e il suo stack, le istanze di oggetti sono nell'heap e possono essere condivise tecnicamente attraverso le esecuzioni, non esiste un meccanismo di blocco per questo, ma è possibile crearne uno proprio.
  • il motore di script non esegue alcuna sincronizzazione o blocco quando si utilizzano classi o funzioni esposte ad esso (tramite TdwsUnit, RTTI, ecc.), Così quando si esegue le esecuzioni di script in thread, assicuratevi solo esposto thread-safe roba (occorre prestare particolare attenzione a tale proposito per RTTI, dal momento che gran parte della RTL & VCL non è thread-safe per cominciare)

Eseguire più esecuzioni di uno script è come avere più thread in Delphi, sebbene ogni nuova esecuzione abbia non solo il proprio stack (come i thread di Delphi) ma anche il proprio spazio variabile (in Delphi sarebbe un po 'come se si avesse "thread" var "ovunque). E le esecuzioni DWScript non devono essere nel loro thread, possono essere spostate attraverso thread, o interrogate e utilizzate in un numero inferiore di thread (l'unica limitazione è che ogni esecuzione viene utilizzata da un solo thread alla volta, come menzionato sopra).

Quindi niente impedisce di esporre una funzione che genera un thread (e un'esecuzione corrispondente) in una funzione di script, ma la comunicazione tra le esecuzioni non avverrà tramite variabili condivise (come si potrebbe essere tentati di fare in Delphi) , ma dovrebbe passare attraverso le proprie funzioni esposte (o variabili esterne), i valori di ritorno (usando un approccio "valutare", vedi i test unitari), istanze di oggetti "condivise" o "vars globali".

Con "vars globali", intendo le funzioni definite in dwsGlobalVarsFunctions.pas, che possono essere utilizzate per lo scambio di dati tra l'esecuzione. Per attivarli, basta "usa dwsGlobalVarsFunctions" da qualche parte nel tuo progetto.

Essi espongono una serie di funzioni di lettura/WriteGlobalVar, che permettono la memorizzazione e il recupero varianti denominate in tutte le esecuzioni di script in esecuzione all'interno dello stesso processo Delphi, e quelli legge & scrittura sono "atomica" da un punto di vista filettatura.

+1

Bello avere il "dio padre" di DWS (o nuovo papà) in SO! :) –

+0

Quando un oggetto TdwsProgramExecution viene eseguito in una discussione, un altro thread può chiamare TdwsProgramExecution.EndProgram in modo sicuro? – FHannes

+0

No, ma è possibile chiamare Stop per quello (che funziona anche se eseguito da Execute(), piuttosto che manualmente con BeginProgram/RunProgram). Ciò farà sì che lo script abortisca alla prima opportunità sotto il suo controllo, cioè. se il tuo script sta eseguendo una funzione Delphi, si fermerà solo dopo il ritorno da quella funzione. EndProgram esegue cleanup ed è pensato per essere chiamato dal thread in esecuzione. –

3

Non era nemmeno necessario aprire la documentazione DWS. :)

Basta dare un'occhiata at this StackOverflow answer by Eric:

Per esempio, [DWS] è ora in grado di molteplici esecuzioni thread-safe di un singolo script compilato, mentre il vecchio codice di base è costruito attorno alla limitazione che uno script compilato può essere eseguito da un solo thread alla volta.

In breve:

  • Il compilatore DWS non è thread-safe: è necessario creare lo stack di esecuzione all'interno di un thread (non è possibile condividere un'istanza compilatore, è necessario un filo per istanza del compilatore);
  • L'esecuzione di DWS è thread-safe, se si utilizza un'istanza di esecuzione per thread: è possibile eseguire lo stesso script compilato in più thread;
  • La comunicazione tra i thread non è disponibile AFAIK, ma è possibile utilizzare il codice Delphi se è necessaria la sincronizzazione.

Ovviamente, qui è the official documentation page about thread safety in DWS.

ora è possibile avere il maggior numero di esecuzioni di programma per un dato IdwsProgram come si desidera, ogni esecuzione userà la memoria per il suo mucchio & pila solo, l'albero di espressione compilata è condivisa. Entrambe le nuove interfacce utilizzano la gestione della memoria conteggio di riferimento.

+1

Leggendo questo, ho capito che lo so già, ma a meno che non sbaglio, non risponde alla mia domanda ... Non voglio eseguire lo stesso script in più thread, voglio essere esecuzione di più thread all'interno di un singolo script ... – FHannes

+1

AFAIK finora comprendo l'implementazione della classe di esecuzione, non è possibile, in base alla progettazione. Non c'è TThread o così. L'unica possibilità sarà quella di eseguire diversi script all'interno di un thread per ognuno (questo è possibile, ovviamente), quindi provare a fare l'IPC o il mutex tra gli script, proprio come ho scritto nel mio terzo punto: non c'è comunicazione tra thread disponibile da zero. Preferirei raccomandare un'architettura stateless, con alcune strutture dati condivise rese disponibili dalle classi Delphi (ad esempio esposte utilizzando RTTI in DWS). –