Sistema di runtime - Runtime system

Nella programmazione per computer , un sistema runtime , chiamato anche ambiente runtime , implementa principalmente parti di un modello di esecuzione . Questo non deve essere confuso con la fase del ciclo di vita di runtime di un programma, durante la quale il sistema di runtime è in funzione. Quando si tratta il sistema runtime come distinto dall'ambiente runtime (RTE), il primo può essere definito come una parte specifica del software applicativo (IDE) utilizzato per la programmazione , un pezzo di software che fornisce al programmatore un ambiente più conveniente per l'esecuzione di programmi durante la loro produzione ( test e simili) mentre il secondo (RTE) sarebbe l' istanza stessa di un modello di esecuzione applicato al programma sviluppato che viene poi eseguito nel suddetto sistema di runtime .

La maggior parte dei linguaggi di programmazione ha una qualche forma di sistema runtime che fornisce un ambiente in cui vengono eseguiti i programmi. Questo ambiente può affrontare una serie di problemi tra cui la gestione della memoria dell'applicazione , il modo in cui il programma accede alle variabili , i meccanismi per il passaggio dei parametri tra le procedure , l'interfaccia con il sistema operativo e altro. Il compilatore fa ipotesi a seconda del sistema di runtime specifico per generare il codice corretto. In genere il sistema runtime avrà alcune responsabilità per l'impostazione e la gestione dello stack e dell'heap e potrebbe includere funzionalità come la raccolta di rifiuti , i thread o altre funzionalità dinamiche integrate nel linguaggio.

Panoramica

Ogni linguaggio di programmazione specifica un modello di esecuzione e molti implementano almeno parte di quel modello in un sistema runtime. Una possibile definizione di comportamento del sistema runtime, tra le altre, è "qualsiasi comportamento non direttamente attribuibile al programma stesso". Questa definizione include l'inserimento di parametri nello stack prima delle chiamate di funzione, l'esecuzione parallela dei comportamenti correlati e l' I/O del disco .

Con questa definizione, essenzialmente ogni lingua ha un sistema di runtime, inclusi linguaggi compilati , linguaggi interpretati e linguaggi specifici del dominio incorporati . Anche i modelli di esecuzione standalone invocati dall'API , come i Pthread ( thread POSIX ), hanno un sistema di runtime che implementa il comportamento del modello di esecuzione.

La maggior parte dei documenti accademici sui sistemi runtime si concentra sui dettagli di implementazione dei sistemi runtime paralleli. Un esempio notevole di un sistema di runtime parallelo è Cilk , un popolare modello di programmazione parallela. Il toolkit proto-runtime è stato creato per semplificare la creazione di sistemi runtime paralleli.

Oltre al comportamento del modello di esecuzione, un sistema runtime può anche eseguire servizi di supporto come il controllo del tipo , il debug o la generazione e l' ottimizzazione del codice .

Relazione con gli ambienti di runtime

Il sistema runtime è anche il gateway attraverso il quale un programma in esecuzione interagisce con l' ambiente runtime . L'ambiente di runtime include non solo valori di stato accessibili, ma anche entità attive con le quali il programma può interagire durante l'esecuzione. Ad esempio, le variabili di ambiente sono funzionalità di molti sistemi operativi e fanno parte dell'ambiente di runtime; un programma in esecuzione può accedervi tramite il sistema runtime. Allo stesso modo, i dispositivi hardware come dischi o unità DVD sono entità attive con cui un programma può interagire tramite un sistema runtime.

Un'applicazione unica di un ambiente runtime è il suo utilizzo all'interno di un sistema operativo che ne consente solo l'esecuzione. In altre parole, dall'avvio allo spegnimento, l'intero sistema operativo è dedicato solo alle applicazioni in esecuzione in quell'ambiente di runtime. Qualsiasi altro codice che tenti di eseguire o qualsiasi errore nelle applicazioni interromperà l'ambiente di runtime. L'interruzione dell'ambiente di runtime a sua volta interrompe il sistema operativo, interrompendo tutte le elaborazioni e richiedendo un riavvio. Se l'avvio è da memoria di sola lettura, viene creato un sistema a missione singola estremamente sicuro, semplice.

Esempi di tali sistemi runtime in bundle direttamente includono:

  • Tra il 1983 e il 1984, Digital Research ha offerto molte delle proprie applicazioni aziendali e didattiche per PC IBM su floppy disk avviabili in bundle con SpeedStart CP/M-86 , una versione ridotta di CP/M-86 come ambiente di runtime.
  • Alcune versioni autonome di Ventura Publisher (1986–1993), Artline (1988–1991), Timeworks Publisher (1988–1991) e ViewMAX (1990–1992) contenevano speciali versioni runtime di GEM di Digital Research come ambiente di runtime.
  • Alla fine del 1990, JP Software processore riga di comando 's 4DOS era disponibile come optional in una versione speciale runtime per essere collegato con BATCOMP precompilato e criptati processi batch in modo da creare unmodifyable eseguibili da script batch e li eseguito su sistemi senza installato 4DOS .

Esempi

Il sistema runtime del linguaggio C è un particolare insieme di istruzioni inserite dal compilatore nell'immagine eseguibile. Tra le altre cose, queste istruzioni gestiscono lo stack del processo, creano spazio per le variabili locali e copiano i parametri delle chiamate di funzione in cima allo stack.

Spesso non esistono criteri chiari per determinare quali comportamenti linguistici fanno parte del sistema di runtime stesso e quali possono essere determinati da un particolare programma sorgente. Ad esempio, in C, l'impostazione dello stack fa parte del sistema runtime. Non è determinato dalla semantica di un singolo programma perché il comportamento è globalmente invariante: vale su tutte le esecuzioni. Questo comportamento sistematico implementa il modello di esecuzione del linguaggio, al contrario dell'implementazione della semantica del particolare programma (in cui il testo viene tradotto direttamente in codice che calcola i risultati).

Questa separazione tra la semantica di un particolare programma e l'ambiente di runtime si riflette nei diversi modi di compilare un programma: compilare il codice sorgente in un file oggetto che contiene tutte le funzioni rispetto alla compilazione di un intero programma in un eseguibile binario. Il file oggetto conterrà solo il codice assembly relativo alle funzioni incluse, mentre il binario eseguibile conterrà codice aggiuntivo che implementa l'ambiente di runtime. Il file oggetto, da un lato, potrebbe non avere informazioni dall'ambiente di runtime che verranno risolte collegando . D'altra parte, il codice nel file oggetto dipende ancora da ipotesi nel sistema runtime; ad esempio, una funzione può leggere i parametri da un particolare registro o posizione dello stack, a seconda della convenzione di chiamata utilizzata dall'ambiente di runtime.

Un altro esempio è il caso dell'utilizzo di un'interfaccia di programmazione dell'applicazione (API) per interagire con un sistema runtime. Le chiamate a quell'API hanno lo stesso aspetto delle chiamate a una normale libreria software , tuttavia a un certo punto durante la chiamata il modello di esecuzione cambia. Il sistema runtime implementa un modello di esecuzione diverso da quello del linguaggio in cui è scritta la libreria. Una persona che legge il codice di una normale libreria sarebbe in grado di comprendere il comportamento della libreria semplicemente conoscendo la lingua in cui è stata scritta la libreria. Tuttavia, una persona che legge il codice dell'API che richiama un sistema runtime non sarebbe in grado di comprendere il comportamento della chiamata API semplicemente conoscendo la lingua in cui è stata scritta la chiamata. Ad un certo punto, tramite un meccanismo, il modello di esecuzione smette di essere quello della lingua in cui è scritta la chiamata e passa ad essere il modello di esecuzione implementato dal runtime sistema. Ad esempio, l'istruzione trap è un metodo per cambiare i modelli di esecuzione. Questa differenza è ciò che distingue un modello di esecuzione invocato da API, come i Pthread, da una normale libreria software. Sia le chiamate Pthreads che le chiamate alla libreria software vengono invocate tramite un'API, ma il comportamento di Pthreads non può essere compreso in termini di linguaggio della chiamata. Piuttosto, le chiamate Pthreads mettono in gioco un modello di esecuzione esterno, che è implementato dal sistema runtime Pthreads (questo sistema runtime è spesso il kernel del sistema operativo).

Come esempio estremo, la stessa CPU fisica può essere vista come un'implementazione del sistema runtime di uno specifico linguaggio assembly. In questa vista, il modello di esecuzione è implementato dalla CPU fisica e dai sistemi di memoria. Per analogia, i sistemi runtime per linguaggi di livello superiore vengono implementati a loro volta utilizzando altri linguaggi. Ciò crea una gerarchia di sistemi di runtime, con la CPU stessa, o in realtà la sua logica a livello di microcodice o inferiore, che agisce come sistema di runtime di livello più basso.

Funzionalità avanzate

Alcuni linguaggi compilati o interpretati forniscono un'interfaccia che consente al codice dell'applicazione di interagire direttamente con il sistema runtime. Un esempio è la Threadclasse nel linguaggio Java . La classe consente al codice (animato da un thread) di eseguire operazioni come avviare e interrompere altri thread. Normalmente, gli aspetti fondamentali del comportamento di una lingua come la pianificazione delle attività e la gestione delle risorse non sono accessibili in questo modo.

I comportamenti di livello superiore implementati da un sistema runtime possono includere attività come disegnare testo sullo schermo o stabilire una connessione Internet. Capita spesso che anche i sistemi operativi forniscano questo tipo di comportamenti e, quando disponibile, il sistema runtime viene implementato come un livello di astrazione che traduce l'invocazione del sistema runtime in un'invocazione del sistema operativo. Ciò nasconde la complessità o le variazioni dei servizi offerti dai diversi sistemi operativi. Ciò implica anche che il kernel del sistema operativo stesso può essere visualizzato come un sistema runtime e che l'insieme di chiamate del sistema operativo che richiamano i comportamenti del sistema operativo può essere visto come interazioni con un sistema runtime.

Al limite, il sistema runtime può fornire servizi come una macchina P-code o una macchina virtuale , che nascondono anche il set di istruzioni del processore . Questo è l'approccio seguito da molti linguaggi interpretati come AWK e alcuni linguaggi come Java , che sono pensati per essere compilati in un codice di rappresentazione intermedio indipendente dalla macchina (come bytecode ). Questa disposizione semplifica il compito di implementazione del linguaggio e il suo adattamento a macchine diverse e migliora l'efficienza di funzionalità linguistiche sofisticate come la riflessione . Consente inoltre di eseguire lo stesso programma su qualsiasi macchina senza una fase di ricompilazione esplicita, una funzionalità che è diventata molto importante dopo la proliferazione del World Wide Web . Per accelerare l'esecuzione, alcuni sistemi runtime dispongono di una compilazione just-in-time in codice macchina.

Un aspetto moderno dei sistemi di runtime sono i comportamenti di esecuzione parallela, come i comportamenti esibiti dai costrutti mutex in Pthread e dai costrutti di sezione parallela in OpenMP . Un sistema runtime con tali comportamenti di esecuzione parallela può essere modularizzato secondo l'approccio proto-runtime.

Storia

I primi esempi notevoli di sistemi runtime sono gli interpreti per BASIC e Lisp . Questi ambienti includevano anche un garbage collector . Forth è un primo esempio di linguaggio progettato per essere compilato in un codice di rappresentazione intermedio; il suo sistema di runtime era una macchina virtuale che interpretava quel codice. Un altro esempio popolare, anche se teorico, è il computer MIX di Donald Knuth .

Nei linguaggi C e successivi che supportavano l'allocazione dinamica della memoria, il sistema runtime includeva anche una libreria che gestiva il pool di memoria del programma.

Nei linguaggi di programmazione orientati agli oggetti , il sistema runtime era spesso anche responsabile del controllo dinamico dei tipi e della risoluzione dei riferimenti ai metodi.

Guarda anche

Riferimenti

Ulteriori letture