Nowoczesny język programowania z intuicyjnymi abstrakcyjnymi programami współbieżnymi [zamknięte]

40

Jestem zainteresowany nauką programowania współbieżnego, koncentrując się na poziomie aplikacji / użytkownika (nie programowania systemowego). Szukam nowoczesnego języka programowania wysokiego poziomu, który zapewnia intuicyjne abstrakty do pisania współbieżnych aplikacji. Chcę skupić się na językach, które zwiększają wydajność i ukrywają złożoność programowania współbieżnego.

Aby podać kilka przykładów, nie uważam za dobrą opcję pisania kodu wielowątkowego w C, C ++ lub Javie, ponieważ IMHO moja wydajność jest zmniejszona, a ich model programowania nie jest intuicyjny. Z drugiej strony języki, które zwiększają produktywność i oferują bardziej intuicyjne abstrakcje, takie jak Python i moduł wieloprocesowy, Erlang, Clojure, Scala itp. Byłyby dobrym rozwiązaniem.

Co poleciłbyś na podstawie swoich doświadczeń i dlaczego?

EDYCJA: Dziękujemy wszystkim za interesujące odpowiedzi. Trudno jest wyciągać wnioski bez próby, ponieważ jest wielu dobrych kandydatów: Erlang, Clojure, Scala, Groovy i być może Haskell. Głosowałem za najbardziej przekonującymi argumentami, ale wypróbuję wszystkich dobrych kandydatów, zanim zdecyduję, który wybrać :)

faif
źródło
21
To give an example, I don't consider a good option writing multithreaded code in C, C++, or Java. Czemu? On the other hand, Python and the multiprocessing module, Erlang, Clojure, Scala, etc. are some of my options.Znowu dlaczego? Rozwiń swoje pytanie, aby lepiej zdefiniować to, czego faktycznie szukasz.
yannis
2
Czy chcesz nauczyć się programowania równoległego ze wszystkimi problemami, czy chcesz ukryć jego złożoność i skupić się na wydajności?
MAR
@MaR Skoncentruj się na wydajności i ukryj złożoność :)
sakisk 22.11.11
Zauważ, że w wielu z tych języków unika się wielu ważnych pojęć (niektórzy twierdzą, że są rozwiązane), dlatego też C jest naprawdę najlepszym językiem do nauki współbieżności. (A przynajmniej tak mi się wydaje; nie wiem wystarczająco dużo o wszystkich wymienionych językach). Zwiększenie wydajności jest często sprzeczne z kompleksowym uczeniem się.
user606723,
1
@DeadMG Ich problemem jest zmniejszona produktywność. Nie chcę skupiać się na składni języka zamiast na problemie. Zdecydowanie nie chcę skończyć z impasem. Jako prosty przykład chcę użyć prostych instrukcji, takich jak begin transaction end transactioni wszystko w środku powinno być wolne od impasu i albo odnieść sukces, albo upaść jako całość.
sakisk

Odpowiedzi:

33

Prawie na pewno powinieneś spojrzeć na Clojure - moim zdaniem jest to najlepszy nowoczesny język do programowania wielordzeniowego i jest niezwykle produktywny.

Kluczowe cechy:

  • Jest to język funkcjonalny , który jest dobrodziejstwem zarówno dla współbieżności, jak i dla twojej zdolności do rozwijania się przy użyciu abstrakcji wyższego poziomu. Posiada w pełni niezmienne trwałe struktury danych i leniwe sekwencje, które będą znane każdemu, kto ma doświadczenie w językach funkcjonalnych, takich jak Haskell.
  • Posiada bardzo nowatorski system pamięci transakcyjnej umożliwiający równoczesny dostęp do stanu zmiennego bez blokady. Zapewnienie bezpieczeństwa współbieżności kodu jest często tak proste, jak umieszczenie go w bloku (dosync ....).
  • To Lisp - co czyni go niezwykle wydajnym do metaprogramowania makr i generowania kodu. Może to przynieść znaczące korzyści w zakresie wydajności (esej Paula Grahama - „Beating The Averages”)
  • Jest to język JVM - więc nie tylko uzyskujesz dostęp do ogromnej gamy bibliotek i narzędzi w ekosystemie Java, ale także czerpiesz korzyści z ogromnego wysiłku inżynieryjnego, który włożony został w uczynienie JVM skuteczną platformą dla współbieżnych aplikacji po stronie serwera. Ze względów praktycznych daje to ogromną przewagę nad językami, które nie mają tego rodzaju podstaw.
  • Jest dynamiczny - co skutkuje bardzo zwięzłym kodem i dużą produktywnością. Należy jednak pamiętać, że w razie potrzeby można użyć opcjonalnych wskazówek typu statycznego dla wydajności.
  • Język został zaprojektowany wokół abstrakcji, co jest nieco trudne do wyjaśnienia, ale efektem netto jest to, że otrzymujesz zestaw względnie ortogonalnych cech, które możesz połączyć, aby rozwiązać swoje problemy. Przykładem może być abstrakcja sekwencji, która umożliwia pisanie kodu, który obsługuje każdy „sekwencyjny” typ obiektu (który obejmuje wszystko od list, ciągów, tablic Java, nieskończonych leniwych sekwencji, linii odczytywanych z pliku itp.)
  • Istnieje świetna społeczność - pomocna, wnikliwa, ale co najważniejsze bardzo pragmatyczna - w Clojure nacisk kładziony jest na „załatwianie spraw”.

Niektóre próbki mini-kodu ze skośną współbieżnością:

;; define and launch a future to execute do-something in another thread
(def a (future (do-something)))

;; wait for the future to finish and print its return value
(println @a)

;; call two functions protected in a single STM transaction
(dosync
  (function-one)
  (function-two))

W szczególności warto obejrzeć jeden lub więcej z tych filmów:

mikera
źródło
21
Deklaracje typów statycznych w silnie typowanych językach nie mają na celu „poprawienia wydajności tam, gdzie jest to potrzebne”, i mam już dość tego, że Lisp opowiada się za wypróbowaniem tego starego słomkarza. Deklaracje typów mają dwa cele: zapewnienie pewnych gwarancji poprawności w czasie kompilacji oraz ułatwienie odczytu kodu, szczególnie dla kogoś innego niż oryginalny autor. Z natury lepsza wydajność pisania statycznego to tylko bonus.
Mason Wheeler,
8
Ostatnio musiałem pracować z kodem JavaScript innego programisty i to jest najbardziej bolesna część tego procesu: bez żadnych argumentów funkcji, muszę przeszukiwać całą bazę kodu, aby dowiedzieć się, co mają zrobić być i co mogą zrobić w oparciu o to, skąd są wywoływani. Nie byłoby problemu, gdyby JavaScript zachował system typów C oprócz swojej ogólnej składni.
Mason Wheeler,
1
@MasonWheeler: IMHO, jeśli nie możesz dowiedzieć się, jak wywołać funkcję bez adnotacji typu, jest to problem z dokumentacją (lub jej brakiem). Nawet w językach pisanych kaczych wszystko zwykle musi spełniać pewne ograniczenia strukturalne (np. Musi obsługiwać operacje arytmetyczne, musi być iterowalny, musi być indeksowalny itp.). Typy statyczne pomogłoby tylko minimalnie, bo nie dałby wiele wskazówkę o co funkcja robi .
dsimcha
2
@Mason Nigdy nie powiedziałem, że deklaracje typu statycznego nie mają innych zalet. W rzeczywistości lubię deklaracje typu statycznego z dokładnie określonych powodów. Jednak podoba mi się również wzrost wydajności pisania dynamicznego. To jest kompromis. Jeśli masz dobry zestaw testów, ogólnie uważam, że łagodzi to wiele wad dynamicznego pisania, zarówno pod względem zapewniania poprawności, jak i dostarczania przykładowego kodu, aby pomóc początkującym zrozumieć prawidłowe użycie. YMMV.
mikera
1
@dsimcha - alternatywą dla projektowania wokół abstrakcji byłoby zaprojektowanie wokół konkretnej implementacji. Na przykład większość starych funkcji Lisp działała tylko na połączonych listach przechowywanych w komórkach Cons. Potrzebne były różne funkcje dla różnych struktur danych. W Clojure podstawowa funkcja biblioteki działa na dowolnej sekwencji (jak w odpowiedzi).
mikera
27

Możesz spróbować D. Oferuje trzy modele. Polecam pierwszy lub drugi.

  1. standardowa waluta . Jeśli używasz tego modułu do wszystkich potrzeb związanych ze współbieżnością, kombinacja języka i biblioteki standardowej wymusza izolację między wątkami. Wątki komunikują się przede wszystkim poprzez przekazywanie wiadomości, z ograniczoną obsługą pamięci współużytkowanej w sposób, który sprzyja „bezpieczeństwu na pierwszym miejscu” i uniemożliwia wyścigi danych niskiego poziomu. Niestety dokumentacja std.concurrency wymaga ulepszenia, ale model został udokumentowany w wolnym rozdziale książki Andrei Alexandrescu „The D Programming Language”.

  2. równoległy standard . Ten moduł został zaprojektowany specjalnie dla równoległości wielordzeniowej zamiast współbieżności ogólnej. ( Współbieżność i równoległość nie są tym samym, chociaż współbieżność jest niezbędna do implementacji równoległości ) . Ponieważ cały punkt równoległości dotyczy wydajności, std.parallelism nie daje żadnych gwarancji izolacji, ponieważ utrudniają pisanie wydajnego kodu równoległego. Jednak usuwa wiele podatnych na błędy szczegółów niskiego poziomu, więc bardzo trudno jest spieprzyć, jeśli równoległe obciążenia, które ręcznie zweryfikowałeś, są od siebie niezależne.

  3. core.thread to niskopoziomowe opakowanie dla interfejsów API wątków specyficznych dla systemu operacyjnego. Zarówno std.concurrency, jak i std.parallelism używają go pod maską, ale zalecałbym używanie go tylko wtedy, gdy piszesz własną bibliotekę współbieżności lub znajdujesz jakiś absurdalny przypadek narożny, którego nie da się dobrze zrobić ani w standardzie standardowym, ani w standardzie .konkurencja. Nikt nie powinien używać czegoś tak niskiego poziomu do codziennej pracy.

dsimcha
źródło
Powinieneś był wspomnieć o niezmienności / czystości, domyślnym przechowywaniu lokalnym wątku i współużytkowaniu, które narzuca mutację w kolejności sekwencyjnej. Są to języki, których brakuje w C / C ++ do pisania kodu współbieżnego.
deadalnix
@deadalnix: Dla mnie większość z nich to szczegóły modelu std.concurrency (jak wymuszana jest izolacja). Chciałem, aby ten post był zwięzły.
dsimcha
Właściwie nie. Konkurencyjność wymaga zarówno obsługi biblioteki ORAZ języka.
deadalnix
@deadalnix: Racja, ale zostały one wprowadzone głównie w celu obsługi standardowej waluty.
dsimcha
23

Erlang jest zdecydowanie świetną opcją, ale czymś bardziej praktycznym może być Go , nowy język Google.

Nie jest tak daleko od innych popularnych języków, więc zazwyczaj łatwo jest go zdobyć, jeśli znasz już inne „łatwe” języki. Wiele osób porównuje go z Pythonem, a nawet Luą, pod kątem tego, jak „wygodne” jest programowanie.

Javier
źródło
@faif pyta o poziom aplikacji / użytkownika, a nie o równoczesne programowanie systemów. Jak Erlang to pasuje?
Chiron
@Raynos: Zależy od społeczności.
Donal Fellows,
@DonalFellowss the right, myślę, że moje stwierdzenie było zbyt wąskie
Raynos
1
@Chiron: Erlang to język programowania, służy do tworzenia aplikacji. Zazwyczaj aplikacje obsługujące wiele procesów. Nie wiem, gdzie to pasuje, jako „równoczesne programowanie systemów”, nie słyszałem o żadnym systemie operacyjnym napisanym w Erlangu.
Javier
1
Po krótkim spojrzeniu w samouczku Go chcę powiedzieć, że IMHO język ze składnią podobną do C, który wykorzystuje (ograniczone) wskaźniki, zdecydowanie nie jest nowoczesnym językiem, który zwiększa produktywność.
sakisk
23

Spójrz na programowanie równoległe Microsoft dla .net. To jest bardzo intuicyjne.

Wiele komputerów osobistych i stacji roboczych ma dwa lub cztery rdzenie (czyli procesory), które umożliwiają jednoczesne wykonywanie wielu wątków. Oczekuje się, że komputery w najbliższej przyszłości będą miały znacznie więcej rdzeni. Aby skorzystać ze sprzętu dzisiejszego i jutra, możesz zrównoleglać swój kod, aby rozdzielić pracę na wiele procesorów. W przeszłości równoległość wymagała niskopoziomowej manipulacji wątkami i zamkami. Visual Studio 2010 i .NET Framework 4 rozszerzają obsługę programowania równoległego, zapewniając nowe środowisko wykonawcze, nowe typy bibliotek klas i nowe narzędzia diagnostyczne. Funkcje te upraszczają tworzenie równoległe, dzięki czemu można pisać wydajny, drobnoziarnisty i skalowalny kod równoległy w naturalnym języku bez konieczności bezpośredniej pracy z wątkami lub pulą wątków. http://i.msdn.microsoft.com/dynimg/IC292903.png

A ----------------------- -----
źródło
+1 To jest dokładnie to, o co prosi. Chociaż w przypadku wystąpienia problemów trudno będzie je debugować bez zrozumienia współbieżności na niższym poziomie. Nie wspominając o tym, że przyjęcie tego jako początkującego w C # może okazać się ... interesujące.
P.Brian.Mackey
@ P.Brian.Mackey - Zgadzam się. Nie jest to jednak rzadkie, nie byłoby łatwo porównać to z używaniem ORM, gdy nie do końca rozumie się model relacyjny i SQL ...
Otávio Décio
1
Zwłaszcza PLINQ. Chociaż jest użyteczny tylko w przypadku niewielkiej części zadań, może być bardzo łatwy w użyciu.
svick
21

Zarówno Erlang, jak i Scala mają opartą na aktorach współbieżność , którą uważam za bardzo intuicyjną i łatwą do nauczenia się.

Model aktora w informatyce to matematyczny model współbieżnych obliczeń, który traktuje „aktorów” jako uniwersalne prymitywy współbieżnych obliczeń cyfrowych: w odpowiedzi na otrzymany komunikat aktor może podejmować lokalne decyzje, tworzyć więcej aktorów, wysyłać więcej wiadomości i określić, jak odpowiedzieć na kolejny otrzymany komunikat ... Został on wykorzystany zarówno jako podstawa teoretycznego zrozumienia obliczeń, jak i jako podstawa teoretyczna dla kilku praktycznych implementacji współbieżnych systemów.

TMN
źródło
19

Uczę się teraz o Haskell i lektura tego artykułu przekonała mnie, że Haskell jest dobrą opcją do równoczesnego programowania. Ponieważ jest on czysto funkcjonalny (system typów wie, czy funkcja wykonuje jakieś dane wejściowe, wyjściowe lub odczytuje / modyfikuje stan globalny), może robić takie rzeczy jak Software Transactional Memory (bardzo ładnie podsumowane w powyższym artykule), który zachowuje się podobnie do transakcji w bazach danych - dostajesz mnóstwo fajnych rzeczy, takich jak atomowość, z odrobiną dodatkowego cukru. AFAIK, nici Haskell są również bardzo lekkie. Oprócz tego, fakt, że Haskell jest czysto funkcjonalny, pozwala na wykonywanie nawet prostych zadań równolegle przy użyciu niewiele więcej niż jednego słowa kluczowego (par). źródło

AlexWebr
źródło
7

Język Google GO ma kilka interesujących narzędzi do współbieżności - to kolejna fajna rzecz do wypróbowania. Zobacz: http://golang.org/doc/effective_go.html#concurrency i przeczytaj trochę przykładów.

Współbieżne programowanie jest dużym tematem i jest tu miejsce tylko na niektóre najważniejsze wydarzenia związane z Go.

Równoczesne programowanie w wielu środowiskach jest utrudnione przez subtelności wymagane do wdrożenia poprawnego dostępu do zmiennych współdzielonych. Go zachęca do innego podejścia, w którym wspólne wartości są przekazywane w kanałach i w rzeczywistości nigdy nie są aktywnie dzielone przez osobne wątki wykonania. Tylko jeden goroutine ma dostęp do wartości w danym momencie. Z założenia wyścigi danych nie mogą wystąpić. Aby zachęcić do takiego sposobu myślenia, zredukowaliśmy go do hasła:

Nie komunikuj się, dzieląc pamięć; zamiast tego współdziel pamięć, komunikując się.

Podejście to można posunąć za daleko. Zliczanie referencji można najlepiej wykonać, umieszczając na przykład muteks wokół zmiennej całkowitej. Ale jako podejście na wysokim poziomie, wykorzystanie kanałów do kontroli dostępu ułatwia pisanie przejrzystych, poprawnych programów.

Jednym ze sposobów myślenia o tym modelu jest rozważenie typowego jednowątkowego programu działającego na jednym procesorze. Nie ma potrzeby prymitywów synchronizacji. Teraz uruchom inną taką instancję; też nie wymaga synchronizacji. Teraz pozwólcie tym dwóm się porozumieć; jeśli komunikacja jest synchronizatorem, nadal nie ma potrzeby innej synchronizacji. Na przykład rurociągi uniksowe idealnie pasują do tego modelu. Chociaż podejście Go do współbieżności wywodzi się z komunikacyjnych procesów sekwencyjnych Hoare'a (CSP), można je również postrzegać jako bezpieczną generację uniksowych potoków ...

komara
źródło
6

W następnej wersji C # sprawia, że ​​jest to nawet łatwiejsze niż pokazuje ten schemat. Istnieją dwa nowe słowa kluczowe Async i Await.

Async jest używany jako modyfikator funkcji i mówi „ta operacja wykonuje swoją pracę na innym wątku.

Oczekiwanie jest używane w funkcji Asynchronicznej i tam właśnie dzieje się magia. Zasadniczo Oczekiwanie informuje kompilator, aby uruchomił operację po słowie kluczowym w osobnym wątku i czekał na wyniki. Każdy kod po wywołaniu oczekującym jest uruchamiany po operacji.

RÓWNIEŻ operacja synchronizuje się z wątkiem wywołującym (więc jeśli wykonujesz operację asynchroniczną w odpowiedzi na kliknięcie przycisku, nie musisz ręcznie ręcznie przesyłać wiadomości z powrotem do wątku interfejsu użytkownika). Dwa małe słowa kluczowe i masz dużą moc współbieżności. Przeczytaj więcej tutaj

Michael Brown
źródło
Zauważ, że każdy przyzwoity kompilator OS C # obsługuje już C # 5, asynchronizuje i czeka.
Raynos,
Zasadniczo Oczekiwanie informuje kompilator, aby uruchomił operację po słowie kluczowym w osobnym wątku i czekał na wyniki. Zastanawiam się, czy ta odpowiedź jest poprawna - async oczekuje nie dotyczy wątków. Ten artykuł wyjaśnia, że ​​jest fajny: Nie ma wątku
sventevit
Słuszna uwaga. Chyba mówiłem o tym po prostu. To, co faktycznie się dzieje, to „kontynuacja”, która subskrybuje zdarzenie zadania w oczekiwaniu na zakończenie. I tak, niektóre operacje We / Wy i thread.sleep () (które w zasadzie reagują na przerwanie zegara) nie mają wątku. ale co z ręcznie wykonanymi zadaniami, które nie przypominają We / Wy, powiedzmy, że stworzyliśmy oczekiwany kalkulator Fibonacciego? Technicznie rzecz biorąc, artykuł ma rację „Nie ma wątku”, ale w rzeczywistości nigdy nie był, zawsze była to koncepcja, w której ukryliśmy szczegóły tego, co system operacyjny dla nas robi.
Michael Brown,
6

Nadal polecam C ++. Jest więcej niż zdolny do niezbędnych abstrakcji do napisania przyzwoitego współbieżnego kodu. Przytłaczające prawdopodobieństwo jest takie, że po prostu masz kiepską bibliotekę do wykonania zadania, ponieważ dobre biblioteki do wykonywania zadania są stosunkowo nowe, a wiedza na temat używania C ++ dobrze nie jest powszechna. TBB Intela istnieje już od kilku lat, a licencja PPL firmy Microsoft jest wysyłana dopiero od zeszłego roku.

Jeśli używasz czegoś takiego jak TBB lub PPL, to kod współbieżny nie jest do końca trywialny , o ile współbieżność nigdy nie jest trywialna, ale daleka od uciążliwego. Jeśli używasz bezpośrednio wątków pthreads lub Win32, nic dziwnego, że ci się nie podoba - praktycznie piszesz w asemblerze z takimi funkcjami. Ale z PPL mówisz o standardowych algorytmach funkcjonalnych, które są dla Ciebie sparaliżowane, ogólnych strukturach danych dla równoczesnego dostępu i tego rodzaju dobrych rzeczach.

DeadMG
źródło
1
Sprawdź Boost.Threads lub C ++ 0x std::thread(lub std::tr1::thread). To właściwie bardzo dobra abstrakcja, IMO.
greyfade,
1
@greyfade: Nie mają absolutnie nic na PPL ani TBB. boost::threadto tylko opakowanie systemu operacyjnego z niewielkim RAII. PPL i TBB to prawdziwe współbieżne algorytmy, kontenery itp.
DeadMG
6

Potrzebna jest tutaj wtyczka do Ady , ponieważ ma ona wszystkie abstrakcje najwyższego poziomu dla równoległości i współbieżności. inaczej znany jako zadanie . Również, gdy OP poprosił o intuicyjne (subiektywne kryteria!), Myślę, że można docenić inne podejście do świata zorientowanego na java.

NWS
źródło
5

Sugerowałbym Groovy / Java / GPars, jeśli możesz być oparty na JVM, ponieważ pozwala on aktorom, przepływowi danych, komunikowaniu procesów sekwencyjnych (CSP), równoległości danych, programowej pamięci transakcyjnej (STM), agentom ... Chodzi o to, że tam jest jest wiele modeli współbieżności i równoległości wysokiego poziomu, z których każdy ma inne „słodkie punkty”. Nie chcesz używać modelu, który nie jest w harmonii z rozwiązaniem problemu, który próbujesz zbudować. Języki i frameworki z jednym modelem zmuszają cię do hakowania algorytmów.

Oczywiście mogę być postrzegany jako stronniczy, ponieważ jestem współtwórcą Groovy i GPars. Z drugiej strony pracuję z CSP i Pythonem, por. Python-CSP.

Kolejną kwestią jest to, że pierwotne pytanie dotyczy nauki, a nie pisania systemu produkcyjnego. Tak więc kombinacja Groovy / Java / GPars jest dobrym sposobem uczenia się, nawet jeśli ostateczne prace produkcyjne są wykonywane w C ++ przy użyciu czegoś takiego jak Just :: Thread Pro lub TBB, a nie oparte na JVM.

(Niektóre całkowicie uzasadnione linki URL musiały zostać usunięte z powodu paniki na temat spamowania przez witrynę hosta).

Russel Winder
źródło
Russel, jeśli chcesz, możesz mi powiedzieć, co chcesz połączyć w pokoju czatu, a ja dodam je dla ciebie: chat.stackexchange.com/rooms/21/programmers
Dan McGrath
4

Co z Clojure? Możesz użyć Swing na przykład, ale lubisz program do jednoczesnego programowania Clojure? Clojure ma całkiem dobrą integrację z Javą.

Czy zastanawiałeś się także nad strukturą Java 7 Fork / Join ?

Chiron
źródło
2

Możesz także zajrzeć do Groovy i biblioteki GPars . GPars BTW jest nieco podobny do .NET Parallel Extension wspomnianego w innej odpowiedzi, ale elastyczna składnia Groovys sprawia, że ​​w niektórych okolicznościach lepiej go czyta.

Christian Horsdal
źródło
0

Scala został kilkakrotnie wspomniany w pytaniach i odpowiedziach, ale nie widziałem odniesienia do Akka, która jest implementacją aktora, której można używać zarówno ze Scalą, jak i Javą.

Giorgio
źródło
Co jest nie tak z tą odpowiedzią? Żadna inna odpowiedź nie wspomina akka, a akka implementuje abstrakcję wysokiego poziomu dla programowania współbieżnego.
Giorgio
-1

Myślę, że to zależy od tego, co budujesz. Aplikacje komputerowe czy serwer? Słyszałem, że (ale nie mam osobistego doświadczenia) node.js doskonale nadaje się do równoczesnego programowania serwerów (zarówno pod względem pisania kodu, jak i wydajności). Gdybym chciał napisać nową aplikację serwerową, prawdopodobnie spróbowałbym tego. Nie jestem pewien co do aplikacji komputerowych ... Napisałem sporo rzeczy w języku C # i jest kilka narzędzi, które ładnie ukrywają złożoność, choć w innych przypadkach musisz sobie z tym poradzić.

Aerik
źródło
-1

Mogę za to trafić, ale czy przeczytałeś rozdział 7 TAOUP ? Sekcja, o której szczególnie myślę, to wątki a procesy. Odkryłem, że koncepcja równoczesnego przetwarzania sprawia, że ​​większość ludzi myśli o wątkach, ale nigdy nie widziałem przypadku, w którym wątek jest łatwiejszy i szybszy w użyciu niż tworzenie procesu potomnego.

Wszystkie szczegóły obsługi współbieżności przekazujesz inteligentnym facetom, którzy zbudowali Twój system operacyjny. Istnieje już wiele metod komunikacji i nie musisz się martwić blokowaniem współdzielonych zasobów. Zasadniczo wątki to hack wydajnościowy, który podlega zasadzie optymalizacji. Nie optymalizuj, jeśli nie testowałeś pod kątem konieczności.

Znajdź dobrą bibliotekę podprocesów, na przykład wysłannika Pythona . Lub możesz po prostu napisać kilka oddzielnych programów w C i napisać inny program „master”, aby użyć fork i pipe do spawnowania i komunikacji z podprocesami.

Spencer Rathbun
źródło
3
Jest to przeciwieństwo tego, co OP wyraźnie chce… spawnowanie procesu jest tak samo niskie, jak ręczne spawnowanie wątku. OP jest zainteresowany wysokopoziomowymi abstrakcjami współbieżności.
Konrad Rudolph