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ć :)
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.begin transaction
end transaction
i wszystko w środku powinno być wolne od impasu i albo odnieść sukces, albo upaść jako całość.Odpowiedzi:
Prawie na pewno powinieneś spojrzeć na Clojure - moim zdaniem jest to najlepszy nowoczesny język do programowania wielordzeniowego i jest niezwykle produktywny.
Kluczowe cechy:
Niektóre próbki mini-kodu ze skośną współbieżnością:
W szczególności warto obejrzeć jeden lub więcej z tych filmów:
źródło
Możesz spróbować D. Oferuje trzy modele. Polecam pierwszy lub drugi.
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”.
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.
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.
źródło
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.
źródło
Spójrz na programowanie równoległe Microsoft dla .net. To jest bardzo intuicyjne.
źródło
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ę.
źródło
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
źródło
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.
źródło
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
źródło
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.
źródło
std::thread
(lubstd::tr1::thread
). To właściwie bardzo dobra abstrakcja, IMO.boost::thread
to tylko opakowanie systemu operacyjnego z niewielkim RAII. PPL i TBB to prawdziwe współbieżne algorytmy, kontenery itp.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.
źródło
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).
źródło
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 ?
źródło
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.
źródło
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ą.
źródło
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ć.
źródło
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.
źródło