Linguaggio di programmazione in cui ogni funzione chiamata / blocco viene eseguita in un thread separato? [chiuso]

26

Attualmente sto creando un linguaggio di programmazione per divertimento dove l'idea è che ogni chiamata di funzione / nuovo blocco (se clausole, cicli, ecc.) funzionerà in un thread separato. Invece di creare nuovi Thread lo standard dovrebbe essere che lo faccia automaticamente, e se vuoi che venga eseguito nel thread principale dovrai specificarlo.

Non sono informato sulla programmazione parallela multi-thread, ma conosco le basi (Futures, thread safe objects). Quindi mi chiedo come un linguaggio del genere possa sembrare sintattico e se è possibile anche cominciare con? L'obiettivo non è renderlo "utile", è più per il divertimento e un'esperienza di apprendimento.

(Mi dispiace se questo è il posto sbagliato da pubblicare. Se è così, sarei lieto di apprezzare se mi indichi il posto giusto dove è consentita una domanda come la mia.)

    
posta Grimbox 28.02.2017 - 18:40
fonte

10 risposte

39

every function call/new block (if clauses, loops etc) will work in a separate thread.

Leggi molto altro su continuazioni e continuation-passing style (e la loro relazione con i thread o le coroutine) suggerisco di leggere SICP & Lisp In Small Pieces . Inoltre, Programming Pragmatic Language offre una panoramica utile di diverse lingue e ti aiuta a progettare il tuo.

Therefore I'm wondering how such a language could look syntax wise

La sintassi non ha molta importanza per esplorare idee . Semantica conta molto di più. Suggerisco di adottare alcuni S-expr come la sintassi (in modo da poter prototipare usando Scheme e il suo call/cc ) all'inizio.

Una volta che le tue idee saranno più chiare (dopo alcuni esperimenti), potresti discuterle su lambda-the-ultimate , tu potrebbe definire una sintassi più sexy (che conta davvero se vuoi che la gente adotti la tua lingua, e ciò che importa è anche la qualità dell'implementazione, un'implementazione di esempio del software libero, la documentazione, la libreria standard, l'interfaccia di funzione straniera, ecc.) p>     

risposta data 28.02.2017 - 18:52
fonte
37

Potresti essere interessato a leggere la ricerca su dati paralleli Haskell . Se cerchi su youtube, Simon Peyton Jones ha tenuto alcuni interessanti talk relativi all'argomento.

Se ricordo correttamente dai suoi discorsi, nella pura programmazione funzionale, è quasi banale trovare opportunità per creare discussioni. Il suo problema principale nella sua ricerca è avere troppi che sono troppo di breve durata, in modo tale che il sovraccarico di creare discussioni e comunicare i loro risultati superi di gran lunga i benefici del parallelismo. Ad esempio, è facile insegnare a un compilatore a creare 100 thread per calcolare sum $ fmap (+1) <100 length vector> , ma il sovraccarico lo renderà utile?

Il trucco è quindi il consolidamento dei thread in dimensioni utili, senza imporre un onere al programmatore per indicarlo manualmente. È un problema difficile da risolvere per poter utilizzare in modo efficace i PC futuri con migliaia di core.

    
risposta data 28.02.2017 - 20:29
fonte
15

Questo è esattamente ciò che fa Erlang. Gestisce il ricongiungimento dei thread principalmente utilizzando le code. È un concetto brillante ma un po 'difficile da comprendere inizialmente se lo sfondo è più linguistico procedurale. Consiglio vivamente di esaminarlo.

    
risposta data 28.02.2017 - 22:32
fonte
4

Per prima cosa ti consiglio di consultare PROMELA , un linguaggio utilizzato per descrivere un algoritmo concorrente in modo che model checker può forzare brute tutte le possibili esecuzioni per verificare che sia incapace di un comportamento scorretto. (La programmazione concorrente è notoriamente difficile per essere corretta, motivo per cui tali tecniche di verifica sono importanti.) Non esegue tutti i costrutti in thread separati, ma ha sintassi e semantica piuttosto strane perché il suo focus è il nondeterminismo dei programmi concorrenti.

Più astratto, il π-calcolo è un bellissimo approccio alla modellazione del calcolo parallelo. È difficile capire se non si ottiene il libro Sistemi comunicativi e mobili: il calcolo del Pi , di Robin Milner. Mi ha aiutato a pensare al calcolo parallelo in un senso più ampio che "thread multipli che accedono a una memoria condivisa". È piuttosto interessante come le dichiarazioni condizionali, le "gotos" e così via possano essere costruite da primitive più semplici, naturalmente parallele.

Per quanto riguarda la sintassi ... il modo migliore per risolvere questo problema è scrivere alcuni programmi di esempio. Scrivi un programma per ordinare un array, o simultaneamente esegue il ping su diversi server e segnala quale risponde più velocemente, o prova a risolvere un labirinto in parallelo, o cosa no. Mentre lo fai, le cose che mancano dalla tua sintassi diventeranno evidenti e potrai aggiungerle. Dopo aver aggiunto diverse cose, chiediti se hanno qualcosa in comune, e se è così forse puoi trovare un approccio più semplice che può servire a molteplici scopi.

    
risposta data 01.03.2017 - 09:24
fonte
4

Progetti simili sono stati tentati in passato. Suggerisco di leggere i classici per raccogliere idee. (Tutti i collegamenti vanno su Wikipedia)

  • Unity Questo linguaggio era / è usato per insegnare la programmazione parallela. Non penso che sia stato effettivamente implementato. La sintassi è alquanto criptica, ma in pratica hai una raccolta di istruzioni che vengono eseguite in un ordine sconosciuto e ripetutamente finché non c'è più nulla da fare. Questo è il più vicino a quello che chiedi.

  • Occam Questo linguaggio è stato progettato per essere utilizzato, ma non è mai stato realmente utilizzato. Qui c'è una parola chiave PAR che significa che una lista di istruzioni dovrebbe essere eseguita in parallelo.

  • Erlang Un altro linguaggio del mondo reale. Questo è usato dalla compagnia telefonica Ericsson e ha un bel seguito. Hanno lavorato molto per rendere il parallelismo pratico e utilizzabile.

  • Google GO Questo è il mio preferito del gruppo. Concettualmente più o meno come Erlang, ma con una sintassi migliore e il peso di Google dietro di esso. Cosa potrebbe mai andare storto?

Vorrei chiudere con un avvertimento: il parallelismo è molto difficile da ottenere. La maggior parte dei bug nei programmi moderni è il risultato di averlo sbagliato . Sei sicuro di voler andare lì?

    
risposta data 01.03.2017 - 12:03
fonte
3

È possibile ma non sarebbe utile per il 99% di tutte le applicazioni pensabili. La logica è tipicamente legata alla sequenza, è un flusso. Passo dopo passo raggiungi una soluzione a un problema e l'ordine dei passaggi è importante, soprattutto perché l'output di un passaggio verrà inserito per il successivo.

Nei pochi casi in cui hai molte attività che possono essere eseguite indipendentemente l'una dall'altra, è generalmente economico installarle in sequenza prima di farle funzionare in parallelo.

Quindi, penso che il tuo tempo sarebbe meglio speso imparando come usare le funzionalità multi-threading nel tuo linguaggio di programmazione preferito.

    
risposta data 28.02.2017 - 19:39
fonte
2

Il Clojure può valere la pena dare un'occhiata ad alcune idee.

link

Ecco alcuni pensieri: Se chiamiamo un'unità di calcolo che può essere eseguita indipendentemente un compito: 1. Le attività sono indipendenti e possono essere eseguite contemporaneamente 2. Attività diverse richiedono risorse diverse e richiedono tempi diversi per l'esecuzione 3. Pertanto, è necessario pianificare le attività per il massimo rendimento 4. L'unico programma in grado di agire come schedulatore è il sistema operativo

Cose come la distribuzione centralizzata di mele sono un tentativo di fornire tale schedulatore.

Quanto sopra significa che la responsabilità di eseguire le attività non è necessariamente quella del linguaggio di programmazione.

Un secondo pensiero è quello di ridurre il più possibile il peso della programmazione dei sistemi paralleli. L'unico modo per farlo è rimuovere qualsiasi specifica di come qualcosa deve essere fatto dal programma. Un programma dovrebbe specificare solo ciò che dovrebbe essere fatto e il resto dovrebbe avvenire automaticamente.

Quanto sopra probabilmente significa che le lingue dinamiche e la compilazione just in time sono la strada da percorrere.

    
risposta data 01.03.2017 - 15:37
fonte
2

Quello che stai cercando è chiamato parallelismo implicito, e ci sono lingue che hanno esplorato questo concetto, come la strongzza . Tra l'altro, (potenzialmente) esegue cicli in parallelo.

Sfortunatamente, è stato fuori produzione e ci sono molti link morti là fuori, ma puoi ancora trovare alcuni file PDF che galleggiano lì intorno, se cerchi abbastanza google:

link (le specifiche del linguaggio)

link

link

link (paywalled)

Vale la pena notare che in genere non si desidera avviare un thread effettivo per ogni istruzione / espressione, poiché la creazione e l'avvio di thread tendono ad essere costosi - invece, si avrebbe pool di thread su cui postare parti di lavoro che devono essere eseguite . Ma questo è un dettaglio di implementazione.

    
risposta data 01.03.2017 - 17:38
fonte
2

Pur non essendo un linguaggio di programmazione come tale, dovresti dare un'occhiata a VHDL . È usato per descrivere i circuiti digitali, che naturalmente fa tutto in parallelo a meno che tu non specifichi specificamente di farlo in serie. Potrebbe darti qualche idea su come progettare la tua lingua e su quale tipo di logica potrebbe essere adatta.

    
risposta data 01.03.2017 - 09:58
fonte
0

Questo può essere simulato abbastanza facilmente in C ++. Assicurati solo che "ogni" * chiamata di funzione sia implementata da std::future . La gestione del valore restituito viene eseguita semplicemente chiamando .get() sul futuro.

Quindi, puoi prototipizzare la tua lingua compilando in C ++. Questo ci dice anche come sarebbe la sintassi: la differenza principale è che si separa il punto di chiamata (dove sono forniti gli argomenti di input) dal punto di ritorno (dove viene utilizzato l'output della funzione).

(*) Dico "ogni funzione" ma dipende da te ciò che conta come una funzione. memset è un valore intrinseco o una funzione? È l'assegnazione di numeri interi o l'assegnazione di tipi definiti dall'utente una chiamata di funzione?

    
risposta data 01.03.2017 - 11:13
fonte