Estoy interesado en aprender programación concurrente, centrándome en el nivel de aplicación / usuario (no en la programación del sistema). Estoy buscando un lenguaje de programación moderno de alto nivel que proporcione abstracciones intuitivas para escribir aplicaciones concurrentes. Quiero centrarme en los lenguajes que aumentan la productividad y ocultan la complejidad de la programación concurrente.
Para dar algunos ejemplos, no considero una buena opción escribir código multiproceso en C, C ++ o Java porque, en mi humilde opinión, mi productividad se reduce y su modelo de programación no es intuitivo. Por otro lado, los lenguajes que aumentan la productividad y ofrecen abstracciones más intuitivas como Python y el módulo de multiprocesamiento, Erlang, Clojure, Scala, etc. serían buenas opciones.
¿Qué recomendarías según tu experiencia y por qué?
EDITAR: Gracias a todos por sus interesantes respuestas. Es difícil llegar a una conclusión sin intentarlo, ya que hay muchos buenos candidatos: Erlang, Clojure, Scala, Groovy y quizás Haskell. Voté la respuesta con los argumentos más convincentes, pero probaré todos los buenos candidatos antes de decidir cuál elegir :)
To give an example, I don't consider a good option writing multithreaded code in C, C++, or Java
. ¿Por qué?On the other hand, Python and the multiprocessing module, Erlang, Clojure, Scala, etc. are some of my options.
De nuevo por qué? Expande tu pregunta para definir mejor lo que realmente estás buscando.begin transaction
end transaction
y todo lo que contenga debe estar libre de puntos muertos y tener éxito o fallar en su conjunto.Respuestas:
Seguramente debería mirar Clojure : en mi opinión, es el mejor lenguaje moderno para la programación multinúcleo y es extremadamente productivo.
Atributos claves:
Algunos ejemplos de mini códigos con una inclinación de concurrencia:
En particular, vale la pena ver uno o más de estos videos:
fuente
Puedes probar D. Ofrece tres modelos. Recomiendo el primero o el segundo.
std.concurrency . Si usa este módulo para todas sus necesidades de concurrencia, entonces una combinación del idioma y la biblioteca estándar impone el aislamiento entre hilos. Los subprocesos se comunican principalmente a través del envío de mensajes, con compatibilidad limitada para la memoria compartida de una manera que favorece la "seguridad primero" y no permite las carreras de datos de bajo nivel. Desafortunadamente, la documentación de std.concurrency necesita mejoras, pero el modelo está documentado en un capítulo gratuito del libro de Andrei Alexandrescu, "The D Programming Language".
Paralelismo estándar . Este módulo está diseñado específicamente para el paralelismo multinúcleo en lugar de la concurrencia de casos generales. (La concurrencia y el paralelismo no son lo mismo, aunque la concurrencia es necesaria para implementar el paralelismo ) . Dado que todo el punto del paralelismo es el rendimiento, std.parallelism no ofrece garantías de aislamiento porque dificultarían la escritura de código paralelo eficiente. Sin embargo, abstrae muchos detalles de bajo nivel propensos a errores, por lo que es muy difícil arruinarlo si está paralelizando cargas de trabajo que ha verificado manualmente que son mutuamente independientes.
core.thread es un contenedor de bajo nivel sobre las API de subprocesos específicas del sistema operativo. Tanto std.concurrency como std.parallelism lo usan debajo del capó, pero solo recomendaría usarlo si está escribiendo su propia biblioteca de concurrencia o encuentra algún caso de esquina ridículo que no se puede hacer bien en std.parallelism o std .concurrencia. Nadie debería usar algo de este nivel bajo para el trabajo diario.
fuente
Erlang es definitivamente una gran opción, pero algo un poco más práctico podría ser Go , el nuevo lenguaje de Google.
No está tan lejos de otros idiomas comunes, por lo que generalmente es fácil de obtener si ya conoce otros idiomas 'fáciles'. Muchas personas lo comparan con Python o incluso con Lua en términos de cuán "cómodo" es programar.
fuente
Eche un vistazo a la programación paralela de Microsoft para .net. Es muy intuitivo.
fuente
Tanto Erlang como Scala tienen concurrencia basada en actores , lo que me pareció muy intuitivo y fácil de aprender.
fuente
Estoy aprendiendo sobre Haskell en este momento, y leer este artículo me ha convencido de que Haskell es una buena opción para la programación concurrente. Debido a que es puramente funcional (el sistema de tipos sabe si una función realiza alguna entrada, salida o lectura / modificación del estado global), puede hacer cosas como la Memoria transaccional de software (resumida muy bien en el documento anterior) que se comporta de manera similar a las transacciones en bases de datos: obtienes un montón de cosas buenas como la atomicidad con solo un poco de azúcar extra. AFAIK, los hilos Haskell también son muy livianos. Además de estas cosas, el hecho de que Haskell sea puramente funcional permite que incluso tareas simples se ejecuten en paralelo con poco más que una sola palabra clave (par). fuente
fuente
El lenguaje GO de Google tiene algunas herramientas interesantes para la concurrencia, que sería otra cosa divertida de probar. Consulte: http://golang.org/doc/effective_go.html#concurrency y lea un poco para ver ejemplos.
fuente
En la próxima versión, C # lo hace aún más fácil de lo que muestra el diagrama. Hay dos nuevas palabras clave Async y Await.
Async se usa como un modificador de función y dice "esta operación realiza su trabajo en otro hilo.
Await se usa dentro de una función Async, y aquí es donde ocurre la magia. Básicamente, Await le dice al compilador que ejecute la operación siguiendo la palabra clave en un hilo separado y espere los resultados. Cualquier código después de la llamada en espera se ejecuta después de la operación.
TAMBIÉN, la operación se sincroniza con el subproceso de llamada (por lo tanto, si está realizando una operación asincrónica en respuesta a un clic en el botón, no tiene que volver a publicar manualmente en el subproceso de la interfaz de usuario). Dos pequeñas palabras clave y obtienes mucho poder de concurrencia. Lee más aquí
fuente
Todavía recomiendo C ++. Es más que capaz de las abstracciones necesarias para escribir código concurrente decente. La probabilidad abrumadora es que simplemente tiene una biblioteca pobre para hacer el trabajo, ya que las buenas bibliotecas para hacer el trabajo son relativamente nuevas y, de hecho, el conocimiento para usar bien C ++ no es exactamente común. El TBB de Intel solo ha existido durante unos años, y el PPL de Microsoft solo se ha enviado desde el año pasado.
Si usa algo como TBB o PPL, entonces el código concurrente es, bueno, no exactamente trivial para escribir, en la medida en que la concurrencia nunca es trivial, pero está lejos de ser ardua. Si usa hilos pthreads o Win32 directamente, entonces no es de extrañar que no le guste, prácticamente está escribiendo en ensamblador con tales funciones. Pero con el PPL, entonces está hablando de algoritmos funcionales estándar que son paralelos para usted, estructuras de datos genéricos para acceso concurrente y ese tipo de cosas buenas.
fuente
std::thread
(ostd::tr1::thread
). En realidad es una muy buena abstracción, en mi opinión.boost::thread
es solo un contenedor de sistema operativo con un poco de RAII. PPL y TBB son algoritmos, contenedores, etc. concurrentes realesAquí se necesita un enchufe para Ada , ya que tiene todas las abstracciones de nivel superior para paralelismo y concurrencia. también conocido como tasking . Además, como OP pidió intuitivo (¡un criterio subjetivo!), Creo que se podría apreciar un enfoque diferente del mundo centrado en Java.
fuente
Sugeriría Groovy / Java / GPars si puede estar basado en JVM ya que permite actores, flujo de datos, procesos secuenciales de comunicación (CSP), paralelismo de datos, memoria transaccional de software (STM), agentes, ... El punto aquí es que allí Hay muchos modelos de concurrencia y paralelismo de alto nivel, cada uno de los cuales tiene diferentes "puntos clave". No desea utilizar un modelo que no esté en armonía con la solución a un problema que está tratando de construir. Los lenguajes y marcos con un solo modelo lo obligan a piratear algoritmos.
Por supuesto, podría ser visto como parcial ya que soy colaborador de Groovy y GPars. Por otro lado, trabajo con CSP y Python, cf. Python-CSP.
Otro punto es que la pregunta original es sobre aprender, no sobre escribir un sistema de producción. Por lo tanto, la combinación Groovy / Java / GPars es una buena forma de aprender, incluso si el trabajo de producción final se realiza en C ++ utilizando algo como Just :: Thread Pro o TBB en lugar de estar basado en JVM.
(Algunos enlaces URL perfectamente razonables tuvieron que eliminarse debido a un cierto pánico sobre el envío de spam por parte del sitio host).
fuente
¿Qué hay de Clojure? ¿Puede usar Swing, por ejemplo, pero disfruta de la instalación de programación concurrente de Clojure? Clojure tiene una muy buena integración de Java.
Además, ¿ha considerado el framework Java 7 Fork / Join ?
fuente
También es posible que desee ver Groovy y la biblioteca GPars . GPars BTW es algo similar a .NET Parallel Extension mencionado en otra respuesta, pero la sintaxis flexible de Groovys hace que se lea mejor en algunas circunstancias.
fuente
Scala se ha mencionado varias veces en las preguntas y en las respuestas, pero no he visto ninguna referencia a Akka, que es una implementación de actor que se puede usar tanto con Scala como con Java.
fuente
Creo que depende de lo que estés construyendo. ¿Aplicaciones de escritorio o servidor? He escuchado que node.js (pero no tengo experiencia personal) es ideal para la programación concurrente para servidores (tanto en términos de escritura de código como en rendimiento). Si quisiera escribir una nueva aplicación de servidor, probablemente lo probaría. No estoy seguro acerca de las aplicaciones de escritorio ... He escrito una buena cantidad de cosas en C # y hay algunas herramientas que ocultan la complejidad muy bien, aunque para otros casos tienes que lidiar con esto de frente.
fuente
Puede que me golpeen en la cabeza por esto, pero ¿has leído el capítulo 7 de TAOUP ? La sección en la que estoy pensando específicamente es subprocesos vs procesos. Descubrí que el concepto de procesamiento concurrente hace que la mayoría de las personas piense en hilos, sin embargo, nunca he visto una instancia en la que un hilo sea más fácil y rápido de usar que generar un proceso secundario.
Estás sacando a relucir todos los detalles del manejo de la concurrencia a los tipos inteligentes que crearon tu sistema operativo. Ya existen muchos métodos de comunicación, y no tiene que preocuparse por el bloqueo de los recursos compartidos. Básicamente, los subprocesos son un truco de eficiencia, que cae bajo la regla de optimización. No optimices si no has probado la necesidad.
Encuentre una buena biblioteca de subprocesos, como enviado para python . O simplemente podría escribir varios programas separados en C, y escribir otro programa "maestro" para usar fork y pipe para generar y comunicarse con los subprocesos.
fuente