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


26

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

Non sono così informato sulla programmazione multi-thread, parallela, ma conosco le basi (Futures, oggetti thread-safe). Quindi mi chiedo come un linguaggio del genere possa sembrare una sintassi saggia e se è persino possibile iniziare? L'obiettivo non è renderlo "utile", è più per il divertimento e un'esperienza di apprendimento.

(Mi dispiace se questo è il posto sbagliato in cui pubblicare. In tal caso, sarei lieto di apprezzarmi se mi indicassi il posto giusto in cui è consentita una domanda come la mia.)


17
La creazione di thread è semplice. Il trucco con il multi-threading è quando devono parlare tra loro o lavorare con le stesse risorse. In altre parole, non è il biforcazione che è difficile, è i join. Il problema principale che devi risolvere è come lo controlli.
JimmyJames,

20
IMO, non puoi farlo senza estendere seriamente la solita definizione della parola "funzione" o della parola "filo". Potresti voler leggere degli attori se non li conosci già: en.wikipedia.org/wiki/Actor_model
Solomon Slow

9
Ottieni risultati abbastanza dettagliati e scoprirai che le CPU già parallelizzano automaticamente le istruzioni, senza gravare ulteriormente sullo sviluppatore del software. Vedere Esecuzione fuori servizio e processore Superscalar .
8bittree,

8
Sembra davvero orribile. Stavo per spiegare perché, ma Karl Bielefeldt lo ha già fatto.
Mason Wheeler,

1
Che tipo di paradigma vuoi supportare nella tua lingua? Dovrebbe essere imperativo o funzionale? Stai dicendo che tutte le istruzioni verrebbero eseguite contemporaneamente - i blocchi then / else insieme a ciò che li segue?
Bergi,

Risposte:


39

ogni chiamata di funzione / nuovo blocco (se clausole, loop ecc.) funzionerà in un thread separato.

Leggi di più sulle continuazioni e sullo stile del passaggio di continuazione (e sulla loro relazione con discussioni o coroutine). Suggerisco di leggere SICP e Lisp in piccoli pezzi . Inoltre, Programming Pragmatics offre una panoramica utile di diverse lingue e ti aiuterà a progettare le tue.

Pertanto mi chiedo come un linguaggio del genere possa apparire sintatticamente saggio

La sintassi non ha molta importanza per esplorare le idee . La semantica conta molto di più. Suggerisco di adottare una sintassi simile a S-expr (in modo da poter prototipare usando inizialmente Scheme e il suo call / cc ).

Una volta che le tue idee sono più chiare (dopo un po 'di sperimentazione), potresti discuterne su lambda-the-ultimate , potresti definire una sintassi più sexy (che in realtà conta se vuoi che le persone adottino la tua lingua e ciò che conta è anche la qualità di implementazione, implementazione di un esempio di software libero, documentazione, libreria standard, interfaccia di funzione esterna, ecc.)


25
+1 per la menzione del perché la sintassi è irrilevante. Un altro +1 se potessi spiegare perché la sintassi è molto importante.
Jörg W Mittag,

Un buon suggerimento, ma per discutere di cose su LtU vorresti un account e non è banale ottenerne uno dalla mia esperienza.
Mael

1
È necessario utilizzare un pool di thread per ridurre il sovraccarico. en.wikipedia.org/wiki/Thread_pool
shawnhcorey

37

Potresti essere interessato a leggere sulla ricerca sui dati paralleli Haskell . Se cerchi su YouTube, Simon Peyton Jones ha tenuto anche alcuni interessanti discorsi sull'argomento.

Se ricordo bene dai suoi discorsi, nella pura programmazione funzionale, è quasi banale trovare opportunità per creare discussioni. Il suo problema principale nella sua ricerca è di averne troppi di breve durata, in modo tale che il sovraccarico di creare fili e comunicare i loro risultati supera sostanzialmente i benefici del parallelismo. Ad esempio, è facile insegnare a un compilatore a far girare 100 thread per il calcolo sum $ fmap (+1) <100 length vector>, ma il sovraccarico ne varrà la pena?

Il trucco consiste quindi nel consolidare i thread in dimensioni vantaggiose, senza imporre al programmatore un onere per indicarlo manualmente. È un problema difficile che deve essere risolto per utilizzare in modo efficace i PC futuri con migliaia di core.


8
Sarei già felice di lavorare con un PC vecchio stile con solo centinaia di core ...
Hagen von Eitzen,

8
Vorrei sottolineare che per progetti fortemente paralleli ai dati, abbiamo già fatto molta parallelizzazione in modo molto efficace: le GPU sono essenzialmente 200-1000 macchine core (hanno persino la loro gerarchia di memoria).
Delioth,

4
@HagenvonEitzen: Azul Vega JCA (Java Compute Appliance) disponeva di 16 CPU con 54 core ciascuna per un totale di 864 core e non era una macchina a livello di ricerca o prototipo, ma un vero prodotto. Inoltre non riempiva un intero edificio o addirittura un'intera stanza, era un apparecchio di dimensioni da scrivania. Ed era disponibile 9 anni fa. Le GPU erano già state menzionate, tuttavia si trattava di una macchina con 864 core CPU per uso generico .
Jörg W Mittag,

3
Naturalmente, c'è una ragione per cui noi facciamo abbiamo oggi quelli massiccia di GPU di dati in parallelo, ma non più quelli massiccia multi-core CPU per i desktop. I primi sono commercialmente fattibili, i secondi no, e questo perché non è possibile programmarli in modo efficiente.
Salterio

@MSalters forse abbiamo solo bisogno di un numero infinito di scimmie? Oppure, programmi Quantum che eseguono semplicemente ogni possibile operazione ad ogni passo?

15

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


4

Per prima cosa ti consiglierei di guardare PROMELA , un linguaggio usato per descrivere un algoritmo concorrente in modo che un correttore di modelli possa forzare tutte le possibili esecuzioni per verificare che non sia in grado di comportarsi in modo errato. (La programmazione concorrente è notoriamente difficile da ottenere, 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 non determinismo dei programmi concorrenti.

Andando più astratto, il π-calcolo è un bellissimo approccio alla modellazione del calcolo parallelo. È difficile districarsi a meno che non si ottenga il libro Sistemi comunicanti e mobili: The Pi Calculus , di Robin Milner. Mi ha aiutato a pensare al calcolo parallelo in senso lato che "più thread accedono a una memoria condivisa". È piuttosto interessante come affermazioni condizionali, "goto" e così via possano essere costruite da primitivi più semplici e naturalmente paralleli.

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 esegui contemporaneamente il ping di più server e segnala quale risponde più velocemente, oppure prova a risolvere un labirinto in parallelo o quant'altro. Mentre lo fai, le cose che mancano nella tua sintassi diventeranno evidenti e puoi aggiungerle. Dopo aver aggiunto diverse cose, chiediti se hanno qualcosa in comune e, in tal caso, forse puoi trovare un approccio più semplice che può servire a più scopi.


4

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

  • Unità Questa lingua era / è usata per insegnare la programmazione parallela. Non penso che sia stato effettivamente implementato. La sintassi è in qualche modo criptica, ma fondamentalmente hai una raccolta di istruzioni che vengono eseguite in ordine sconosciuto e ripetutamente fino a quando non c'è più nulla da fare. Questo è il più vicino a ciò che chiedi.

  • Occam Questo linguaggio è stato progettato per essere effettivamente utilizzato, ma non ha mai preso piede. Qui c'è una parola chiave PAR che significa che un elenco di istruzioni dovrebbe essere eseguito in parallelo.

  • Erlang Un'altra lingua del mondo reale. Questo è usato dalla compagnia di telecomunicazioni Ericsson e ha un seguito abbastanza. Hanno lavorato molto per rendere il parallelismo pratico e utilizzabile.

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

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


Nessun reato destinato a qualsiasi lingua non presente nel mio elenco. È solo che la mia conoscenza è limitata.
Stig Hemmer

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 si raggiunge una soluzione a un problema e l'ordine dei passaggi è importante, soprattutto perché l'output di un passaggio verrà immesso per il successivo.

Nei pochi casi che hai molte attività che possono essere eseguite indipendentemente l'una dall'altra, è in genere economico impostarle in sequenza prima di lasciarle funzionare in parallelo.

Quindi, penso che sarebbe meglio passare il tempo a imparare come utilizzare le funzionalità multi-thread nel tuo linguaggio di programmazione preferito.


5
Questa è un'ottima risposta a una domanda diversa; OP non sta chiedendo la saggezza di un tale schema, ma semplicemente se può essere fatto e quale sarebbe la "sintassi".
Depresso

9
Coloro che non lo richiedono hanno più bisogno della mia saggezza. Se qualcuno chiede se è possibile scendere una collina in un carrello, la risposta migliore non sarebbe "Puoi scommettere! Assicurati di ingrassare le ruote!". Sarebbe più come "Beh, sì, ma ...".
Martin Maat

Mi ricorda le vecchie istruzioni sulla lingua dell'assemblea EIAO - Esegui in qualsiasi ordine . (E dov'è quella chiave?)

@MartinMaat nessuno si ucciderà scrivendo un linguaggio di programmazione per divertimento
user253751

2

Clojure potrebbe valere la pena dare un'occhiata ad alcune idee.

http://clojure-doc.org/articles/language/concurrency_and_parallelism.html

Ecco alcuni pensieri: Se chiamiamo un'unità di calcolo che può essere eseguita in modo indipendente un'attività: 1. Le attività sono indipendenti, quindi possono essere eseguite contemporaneamente 2. Diverse attività richiedono risorse diverse e richiedono tempi diversi per l'esecuzione 3. Pertanto, le attività devono essere pianificate per la massima produttività 4. L'unico programma in grado di fungere da schedulatore è il sistema operativo

Cose come la spedizione centralizzata di mele sono un tentativo di fornire un tale programmatore.

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

Un secondo pensiero è quello di ridurre il più possibile l'onere della programmazione di sistemi paralleli. L'unico modo per farlo è rimuovere qualsiasi specifica di come fare qualcosa dal programma. Un programma dovrebbe solo specificare cosa dovrebbe essere fatto e il resto dovrebbe avvenire automaticamente.

Quanto sopra probabilmente significa che i linguaggi dinamici e la compilazione just in time sono la strada da percorrere.


2

Quello che stai cercando si chiama parallelismo implicito e ci sono lingue che hanno esplorato questo concetto, come la Fortezza di Sun / Oracle . Tra l'altro, (potenzialmente) esegue cicli in parallelo.

Sfortunatamente, è stato sospeso e ci sono molti link morti là fuori, ma puoi ancora trovare alcuni PDF fluttuanti lì intorno, se google abbastanza forte:

https://www.eecis.udel.edu/~cavazos/cisc879-spring2008/papers/fortress.pdf (le specifiche della lingua)

http://stephane.ducasse.free.fr/Teaching/CoursAnnecy/0506-Master/ForPresentations/Fortress-PLDITutorialSlides9Jun2006.pdf

http://www.oracle.com/technetwork/systems/ts-5206-159453.pdf

http://dl.acm.org/citation.cfm?id=1122972 (paywalled)

Vale la pena notare che in genere non si vorrebbe avviare un thread effettivo per ogni istruzione / espressione, poiché la creazione e l'avvio di thread tende ad essere costoso - invece, si avrebbe un pool di thread in cui si inseriscono bit di lavoro che devono essere eseguiti . Ma questo è un dettaglio di implementazione.


1
+1 per la fortezza di Mantioning ... Mi è piaciuta molto l'idea della lingua. Ero davvero triste quando hanno annunciato che lo sviluppo è stato interrotto ...
Roland Tepp il

2

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


0

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

Quindi, potresti prototipare il tuo linguaggio compilando in C ++. Questo ci dice anche che aspetto avrebbe la sintassi: la differenza principale è che si separa il punto di chiamata (dove vengono forniti gli argomenti di input) dal punto di ritorno (dove viene usato l'output della funzione).

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


E, se rimandate a rispondere a una domanda abbastanza a lungo, di solito la necessità di una risposta scompare. Penso che questo si chiama "Lazy Existing".
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.