web-dev-qa-db-ja.com

直感的な並行プログラミング抽象化を備えた最新のプログラミング言語

アプリケーション/ユーザーレベル(システムプログラミングではない)に焦点を当てて、並行プログラミングの学習に興味があります。並行アプリケーションを作成するための直感的な抽象化を提供する、最新の高水準プログラミング言語を探しています。生産性を高め、並行プログラミングの複雑さを隠す言語に焦点を当てたいと思います。

いくつかの例を示すために、C、C++、またはJavaでマルチスレッドコードを記述する適切なオプションを検討しません。なぜなら、私見では私の生産性が低下し、プログラミングモデルが直感的ではないためです。一方、 Pythonやマルチプロセッシングモジュール、Erlang、Clojure、Scalaなど)のように、生産性を高め、より直感的な抽象化を提供する言語は、良いオプションでしょう。

あなたの経験に基づいて何を勧めますか、そしてその理由は何ですか

編集:あなたの興味深い答えをみんなに感謝します。 Erlang、Clojure、Scala、Groovy、そしておそらくHaskellなど、多くの優れた候補が存在するため、実際に試みずに結論を出すことは困難です。私は最も説得力のある引数で答えを投票しましたが、どれを選ぶかを決める前にすべての良い候補を試してみます:)

41
sakisk

あなたはほぼ間違いなく Clojure を見る必要があります-私の意見では、それはマルチコアプログラミングに最適な最新の言語であり、非常に生産的です。

主な属性:

  • これは関数型言語です。これは、同時実行性と、より高いレベルの抽象化を使用して開発する能力の両方に恩恵をもたらします。 Haskellのような関数型言語の経験がある人なら誰でもおなじみの、完全に不変の永続データ構造と遅延シーケンスを備えています。
  • 変更可能な状態への同時ロックフリーアクセスのための非常に新しいソフトウェアトランザクションメモリシステムを備えています。多くの場合、コードを同時実行的に安全にすることは、それを(dosync ....)ブロックでラップするのと同じくらい簡単です。
  • これは[〜#〜] lisp [〜#〜]で、マクロベースのメタプログラミングとコード生成に非常に強力です。これは重要な 生産性の利点 をもたらす可能性があります(Paul Grahamによるエッセイ-"平均を打つ")
  • これはJVM言語です-Javaエコシステムのライブラリとツールの膨大な配列にアクセスできるだけでなく、これは、JVMを同時サーバー側アプリケーションの効果的なプラットフォームにするために費やされた膨大なエンジニアリングの努力です。これにより、実用上、このような基盤のない言語よりも大きな利点が得られます。
  • それはdynamicです-これは非常に簡潔なコードと多くの生産性をもたらします。ただし、必要に応じて、パフォーマンスのためにオプションの静的型ヒントを使用できることに注意してください。
  • 言語は抽象化を中心に設計されています説明はやや難しいですが、最終的には、問題を解決するために組み合わせることができる比較的直交する機能のセットが得られます。例として、シーケンスの抽象化があります。これにより、オブジェクトのすべての「順次」タイプ(リスト、文字列、Java配列、無限遅延シーケンス、行からのすべてを含む)を処理するコードを記述できますファイルなどから読み込まれる)
  • 素晴らしいコミュニティがあります-役立つ、洞察力がありますが、最も重要なのは非常に実用的です-Clojureの焦点は、一般に「物事を成し遂げる」ことにあります。

並行処理の傾斜があるいくつかのミニコードサンプル:

;; 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))

特に、これらのビデオを1つ以上見る価値があります。

33
mikera

Dを試すことができます。3つのモデルがあります。最初か2番目をお勧めします。

  1. std.concurrency 。すべての同時実行性のニーズにこのモジュールを使用する場合、言語と標準ライブラリの組み合わせにより、スレッド間の分離が強制されます。スレッドは主にメッセージパッシングを介して通信しますが、「セーフティファースト」を優先し、低レベルのデータレースを許可しない方法で共有メモリを限定的にサポートします。残念ながらstd.concurrencyのドキュメントは改善が必要ですが、モデルはAndrei Alexandrescuの本「The D Programming Language」の 無料の章にドキュメント化されています。

  2. std.parallelism 。このモジュールは、一般的なケースの同時実行性ではなく、マルチコア並列処理用に特別に設計されています。 ( 並列性と並列性は同じものではありませんが、並列性を実装するには並列性が必要です。 )並列性の全体のポイントはパフォーマンスであるため、std.parallelismは効率的な並列コードの作成が困難になるため、分離の保証は行いません。ただし、エラーが発生しやすい低レベルの詳細を抽象化しているため、手動で確認したワークロードを相互に独立していることを並列化している場合、失敗するのは非常に困難です。

  3. core.thread は、OS固有のスレッドAPIの低レベルのラッパーです。 std.concurrencyとstd.parallelismはどちらも内部で使用しますが、独自の同時実行ライブラリを作成している場合、またはstd.parallelismまたはstdのいずれでもうまく実行できないとんでもないコーナーケースを見つけた場合にのみ使用することをお勧めします.concurrency。このような低レベルのものを日常の作業に使用することはできません。

27
dsimcha

Microsoftの.net用並列プログラミングを見てください。 非常に直感的です。

多くのパーソナルコンピュータやワークステーションには、複数のスレッドを同時に実行できるようにする2つまたは4つのコア(つまり、CPU)があります。近い将来のコンピューターでは、コアの数が大幅に増えると予想されます。今日および明日のハードウェアを利用するために、コードを並列化して、複数のプロセッサーに作業を分散させることができます。以前は、並列化にはスレッドとロックの低レベルの操作が必要でした。 Visual Studio 2010および.NET Framework 4は、新しいランタイム、新しいクラスライブラリタイプ、および新しい診断ツールを提供することにより、並列プログラミングのサポートを強化します。これらの機能は並列開発を簡素化するため、スレッドやスレッドプールを直接操作する必要なく、自然なイディオムで効率的で細かくスケーラブルな並列コードを記述できます。次の図は、.NET Framework 4の並列プログラミングアーキテクチャの概要を示しています... http://i.msdn.Microsoft.com/dynimg/IC292903.png

23
Otávio Décio

Erlangは間違いなく優れたオプションですが、もう少し実用的なものは Go 、Googleの新しい言語かもしれません。

他の一般的な言語からそれほど遠くないため、他の「簡単な」言語をすでに知っている場合は、通常、簡単に入手できます。多くの人々はそれをPythonまたはLuaと比較して、プログラムするのがいかに「快適」かという点で比較します。

23
Javier

ErlangとScalaには actor-based concurrency があります。これは非常に直感的で習得しやすいことがわかりました。

コンピュータサイエンスのアクターモデルは、「アクター」を同時デジタル計算のユニバーサルプリミティブとして扱う同時計算の数学モデルです。受信したメッセージに応じて、アクターはローカルで決定を行い、より多くのアクターを作成し、より多くのメッセージを送信できます。 、そして受け取った次のメッセージにどのように応答するかを決定します...これは、計算の理論的理解のためのフレームワークとして、および並行システムのいくつかの 実用的な実装 の理論的基礎として使用されています。

21
TMN

私は今、Haskellについて学んでいて、 この論文 を読んで、Haskellが並行プログラミングの優れたオプションであると確信しました。純粋に機能するため(型システムは、関数が入力、出力、またはグローバル状態の読み取り/変更を行うかどうかを認識している)、トランザクションと同様に動作するソフトウェアトランザクションメモリ(上記の論文で非常によくまとめられています)などの処理を実行できます。データベースで-あなたは少しだけ余分な砂糖で原子性のような素晴らしいものの束を取得します。 AFAIK、Haskellスレッドも非常に軽量です。これらに加えて、Haskellは純粋に機能的であるという事実により、単純なタスクでさえ、単一のキーワード(par)を超えることなく並行して実行できます。 ソース

19
user41310

GoogleのGO言語には、並行処理のための興味深いツールがいくつかあります。これは、もう1つの楽しいことです。参照: http://golang.org/doc/effective_go.html#concurrency および例については、少し読んでください。

並行プログラミングは大きなトピックであり、ここにはいくつかのGo固有のハイライトのためのスペースしかありません。

多くの環境での並行プログラミングは、共有変数への正しいアクセスを実装するために必要な機微により困難になっています。 Goは、共有された値がチャネル上で渡され、実際には個別の実行スレッドによって積極的に共有されないという別のアプローチを奨励しています。一度に1つのゴルーチンだけが値にアクセスできます。設計上、データの競合は発生しません。この考え方を奨励するために、私たちはそれをスローガンに減らしました:

メモリを共有して通信しないでください。代わりに、通信してメモリを共有します。

このアプローチは、あまりにも遠くに行くことができます。参照カウントは、たとえば、整数変数の周りにミューテックスを置くことによって最もよく行われます。ただし、高レベルのアプローチとして、チャネルを使用してアクセスを制御すると、明確で正しいプログラムを簡単に作成できます。

このモデルについて考える1つの方法は、1つのCPUで実行される一般的なシングルスレッドプログラムを検討することです。同期プリミティブは必要ありません。次に、別のそのようなインスタンスを実行します。同期も必要ありません。次に、これら2つが通信できるようにします。通信がシンクロナイザである場合、他の同期はまだ必要ありません。たとえば、Unixパイプラインはこのモデルに完全に適合します。 Goの並行性へのアプローチはHoareのCommunicating Sequential Processes(CSP)に由来しますが、Unixパイプのタイプセーフな一般化と見なすこともできます...

7
Aerik

次のバージョンでは、C#により、図が示すよりもさらに簡単になります。 AsyncとAwaitの2つの新しいキーワードがあります。

非同期は関数修飾子として使用され、「この操作は別のスレッドで作業を実行します。

AwaitはAsync関数内で使用され、ここで魔法が起こります。基本的にAwaitは、キーワードに続く操作を別のスレッドで実行し、結果を待つようコンパイラーに指示します。操作の後に、await呼び出しの後のコードが実行されます。

また、操作は呼び出しスレッドに同期します(ボタンのクリックに応答して非同期操作を行っている場合は、UIスレッドに手動でポストバックする必要はありません)。 2つの小さなキーワードを使用すると、多くの同時実行力が得られます。続きを読む こちら

6
Michael Brown

ここには Ada のプラグが必要です。これは、並列処理と並行処理のためのすべての最上位の抽象化を備えているためです。 タスク とも呼ばれます。また、OPが直感的(主観的な基準!)を要求したように、Java中心の世界への別のアプローチが評価されると思います。

6
NWS

私はまだC++をお勧めします。まともな並行コードを作成するために必要な抽象化ができる以上のものです。 goodジョブを実行するためのライブラリーは比較的新しく、実際、C++を上手に使用するための知識は正確に一般的ではないため、圧倒的な確率は、ジョブを実行するための貧弱なライブラリーを持っているということです。 IntelのTBBは数年前から存在しており、MicrosoftのPPLは昨年から出荷されています。

TBBやPPLのようなものを使用する場合、同時実行コードは、厳密にはtrivialと書くのではなく、同時実行性は決して些細なことではありませんが、困難ではありません。 pthreadsまたはWin32スレッドを直接使用する場合、それが気に入らないのも不思議ではありません。そのような関数を使用してアセンブラーで実際に記述していることになります。しかし、PPLに関しては、並列化された標準の関数アルゴリズム、同時アクセス用の汎用データ構造、およびそのような優れたものについて話していることになります。

6
DeadMG

アクター、データフロー、通信シーケンシャルプロセス(CSP)、データ並列処理、ソフトウェアトランザクションメモリ(JVMベース)を使用できるため、JVMベースである場合は Groovy /Java/ GPars をお勧めしますSTM)、エージェント、...ここでのポイントは、それぞれに異なる「スイートスポット」を持つ多くの高レベルの同時実行性および並列性モデルがあることです。構築しようとしている問題のソリューションと調和していないモデルを使用したくない。モデルが1つしかない言語とフレームワークでは、アルゴリズムハッキングが必要になります。

もちろん、私はGroovyとGParsに貢献しているので、偏見があると思われるかもしれません。一方、私はCSPとPythonを使用しています。 Python-CSP。

さらに、元の質問は学習に関するものであり、本番システムの作成に関するものではないということです。したがって、Groovy/Java/GParsの組み合わせは、JVMベースではなく、Just :: Thread ProやTBBのようなものを使用してC++で最終的な本番作業が行われる場合でも、良い学習方法です。

(ホストサイトによるスパム行為についてのパニックのために、いくつかの完全に妥当なURLリンクを削除する必要がありました。)

5
Russel Winder

Clojureはどうですか?たとえばSwingを使用できますが、Clojure並行プログラミング機能を楽しんでいますか? ClojureはかなりよくJava統合されています。

また、あなたは Java 7 Fork/Joinフレームワーク を検討しましたか?

4
Chiron

Groovy および GPars ライブラリを確認することもできます。 GPars BTWは、別の回答で述べた.NET Parallel Extensionにいくらか似ていますが、Groovysの柔軟な構文により、状況によっては読みやすくなります。

2

Scalaは質問と回答で何度も言及されていますが、私は Akka への言及を見たことはありません。これは、ScalaとJava。

0
Giorgio