2010-06-26 25 views
9

Me gustaría comenzar a aprender multihilo en C++. Lo estoy aprendiendo en Java también. En Java, si escribo un programa que usa multiprocesamiento, funcionará en cualquier lugar. Sin embargo, en C++, ¿no confía el multihilo en las API específicas de la plataforma? Si es así, eso parece interferir con la portabilidad.Multithreading en C++ ... ¿por dónde empezar?

¿Cómo puedo hacer multihilo en C++ sin causar problemas de portabilidad? ¿La biblioteca de boost thread es una buena solución?

Como nota al margen - ¿cómo es posible implementar multihilo como biblioteca? ¿No es eso algo que tiene que hacer el compilador?

+1

Como medida de precaución, tendrá que pensar mucho más sobre la seguridad de las cadenas de caracteres en C++. No se puede simplemente rociar las palabras clave de sincronización para los métodos de clase para que sean seguras. Por lo general, utilizará herramientas como mutex u otras formas de secciones críticas, operaciones atómicas, etc. Sin embargo, podrá escribir código multihilo muy eficiente si lo hace bien. Incluso puede escribir sus propios asignadores de memoria con grupos de memoria por subproceso, pero es mucho más bajo y mucho más difícil de escribir para la corrección que Java. – stinky472

+0

(+1) @ stinky472: Es exactamente por eso que quiero aprender multihilo en C++ y en Java. Siento que Java generalmente es bueno para intros de alto nivel para muchos temas, pero simplemente apegarse a Java puede hacer que el programador sea un poco demasiado y no exponerlos a algunos conceptos muy importantes. Por lo tanto, mientras estoy aprendiendo multihilo en Java, estoy buscando aprenderlo simultáneamente en C++ para asegurarme de que estoy aprendiendo todo lo que debería ser. – Cam

Respuesta

13

Si usted no tiene un compilador que apoya C++0x todavía (disponible con el estudio visual C++ 2010, por ejemplo), utilice el refuerzo con hilos. (A menos que use un marco que ya admite el enhebrado, que no es el caso; de lo contrario, no haría la pregunta). Estos hilos de refuerzo se convirtieron en el estándar en el nuevo C++. Antes de ese momento, C++ en sí no tenía hilos.

TBB Threading Building Blocks también podría ser interesante para usted si usted desea aprender otros aspectos de la programación paralela.

En cuanto Qt: si solo deseas soporte roscado es una exageración completa. Tiene tiempos de viaje de ida y vuelta terriblemente lentos desde la compilación hasta el resultado. Es un pensamiento realmente bien diseñado. Pero no es un estándar oficial como los hilos C++ 0x de boost. Por lo tanto, no lo tomaría como primera opción.

+0

Gracias. Todas las respuestas fueron muy buenas, pero esta fue la más informativa. – Cam

3

En C++, sí el enhebrado es específico de la plataforma. Sin embargo, muchas bibliotecas de subprocesos encapsulan los matices del subprocesamiento en varias plataformas, proporcionando una API uniforme con la que escribir su aplicación con subprocesos, para que no tenga que preocuparse por los detalles específicos de la plataforma.

Boost threading library es una muy buena solución.

También estoy recomendando verificar ACE también.

1

para ofrecer una sugerencia diferente de Boost, utilizo Pthreads (o Pthreads-Win32 en Windows). Es una biblioteca barebones muy hágalo usted mismo, pero le proporciona todo lo que necesita y nada más. Es muy liviano en comparación con Boost y puedes encontrar fácilmente envoltorios de C++ a tu alrededor para darte abstracciones de mayor nivel.

+0

La biblioteca de subprocesos de boost es una biblioteca de plantillas "solo encabezado". No crea grandes gastos generales. Ok, el conjunto de archivos necesarios puede ser enorme, pero en el resultado final solo tendrá unos pocos bytes de la instanciación de la plantilla. – jdehaan

+0

@jdehaan: ¿Puedes ampliar lo que quieres decir con "encabezado de plantilla" solo con "biblioteca"? – Cam

+3

Debo admitir que estoy bastante sorprendido también por el "encabezado solo". Esto: 'libboost_thread-vc100-mt-gd-1_43.lib' no se parece a un encabezado. –

4

Vamos a empezar al revés:

¿Cómo es posible implementar enhebrado en una biblioteca?

No es, al menos no en (puro) C++. Esto requiere idioma soporte (el compilador es solo una implementación).

Por el momento se utilizan 2 cosas:

  • código ensamblador para algunas partes (como en la biblioteca pthread)
  • instrucciones específicas del compilador para otros (depende del compilador y plataforma)

Ambos son frágiles y requieren una enorme cantidad de trabajo para la portabilidad. Básicamente significa porciones de #ifdef en el código para probar el compilador y la arquitectura de destino, probar el soporte de algunas directivas, etc. ...

Es por eso que se consideró necesario agregar soporte de subprocesamiento en C++ 0x .

¿Cómo hago multihilo?

Incluso antes de elegir una biblioteca, debe elegir un método. Hay 2 maneras de aplicaciones multiproceso de programación (y se pueden combinar):

  • Comunicar al compartir: esto significa que utilizan mutex, operaciones atómicas, etc ... se puede utilizar pthread en plataformas Linux, pero recomendaría Boost.Thread (entre otros) por su portabilidad.
  • Compartir comunicando: más reciente, y adaptado a cálculos distribuidos, esto proviene de los lenguajes funcionales. Esto significa pasar mensajes de un hilo a otro y no compartir ningún recurso. Puede usar FastFlow o Intel Thread Building Blocks aka TBB.

Puede concebible combinar los dos, pero sería mejor no. Personalmente, encontré la descripción de FastFlow totalmente asombrosa: fomenta la programación sin bloqueos. Además, la principal ventaja del segundo método es que está mejor adaptado a la programación de múltiples procesos y escalas a entornos distribuidos.

Para empezar, recomendaría centrarse en cualquiera de los dos y crear algunas aplicaciones con él. Cuando te sientas cómodo, puedes probar el otro, pero prepárate para comenzar de nuevo, son diferentes.

+0

No depende del compilador admitir hilos, sino hasta el sistema operativo. La forma de hacerlo en C++ puro, por ejemplo, es incluir encabezados pthreads, usar sus funciones y vincular a su lib. El compilador no sabe nada sobre pthreads en sí. – Gianni

+0

Bueno, yo diría que usar una biblioteca basada en ensamblaje no usa C++ puro;) Sin embargo, corregiré el compilador, me refiero al lenguaje. –

+0

@Matthieu, lo que quise decir es que, y la aplicación solo le pide al sistema operativo un hilo, y depende del sistema operativo crear e iniciar el hilo. El ASM o las funciones integradas del compilador (que solo significan más ASM) se usan solo para átomos. Mutexes, Semaphores, Threads mismos son todos hasta el SO. – Gianni

1

, también podría considerar openmp http://openmp.org. Muchos compiladores lo admiten, incluidos MS, GCC/G ++ e Intel. Aunque no se obtiene un control explícito de los hilos, su abstracción de paralelismo de mayor nivel es a veces más eficiente (tanto en el tiempo de codificación como en el tiempo de ejecución), y el código es mucho más fácil de entender. No va a ayudar mucho si está haciendo un trabajo de GUI, pero para el cómputo escalable vale la pena echarle un vistazo.

1

La biblioteca de Boost Threading es probablemente el mejor lugar para comenzar con C++. Te da subprocesos de construcciones, así como todos los mutex y objetos de control que necesitas para escribir una aplicación multihilo de trabajo real.

0

Si está haciendo esto por interés para mejorar su conocimiento de los diferentes modelos de programación y habilidades de lenguaje, entonces la biblioteca de Boost sería un buen camino a seguir. Sin embargo, pensaría largo y tendido sobre la construcción de cualquier aplicación de producción usando C++ de subprocesos múltiples.

C++ es lo suficientemente desafiante a veces para lograr la corrección sin agregar la considerable complejidad de la memoria compartida multi-threading. Incluso los programadores más avezados estarían de acuerdo en que los programas de subprocesos múltiples son extremadamente difíciles de razonar y acertar. Incluso los programas más simples pueden volverse difíciles de probar y depurar rápidamente cuando tienen múltiples subprocesos.

Los lenguajes imperativos como C++ o Java o C# (con sus variables mutables, memoria compartida y primitivas de bloqueo/señalización) son a menudo la forma menos accesible de intentar crear aplicaciones de subprocesos múltiples. Por lo general, las opciones de implementación de un solo subproceso son perfectamente buenas para lograr la mayoría de los problemas de la aplicación en el espacio del usuario (en lugar de kernel o incrustados), incluso en máquinas con varios núcleos.

Si realmente desea construir aplicaciones fiables de "múltiples hilos", le sugiero que consulte los lenguajes funcionales como Erlang, Haskell, F # o Clojure.

2
//This program explains how pthread works, here 5 thread are trying to update a global variable simultaneously but with locking synchronization in maintained 
#include<iostream> 
#include<pthread.h> 
using namespace std ; 

#define MAX_NO_THREAD 5 

    int global_sum = 0 ; 
    pthread_mutex_t lock ; //Declared global lock mutex object 

void *print_fun(void *arg) 
{ 
    cout<<"\nThread id : "<<(int)arg; 
    pthread_mutex_lock(&lock) ; //aquiring lock on piece of code 
    for (int j=0; j<100000000; j++) 
    { 
     global_sum++ ; 
    } 
    pthread_mutex_unlock(&lock) ; //reomving lock on peice of code 
    cout<<"\nGlobal Sum : "<<global_sum ; 
} 

int main() 
{ 
    int i = 0 ; 
    pthread_t threads_obj[MAX_NO_THREAD] ; //Initializing object array for thread 
    pthread_mutex_init(&lock, NULL) ; //Initalinzing lock object for thread 
    int st ; 
    for (i=0; i<5; i++) 
    { 
     pthread_create(&threads_obj[i], NULL, *print_fun, (void *)i) ;//Initializing threads calling function print_fun 
     pthread_join(threads_obj[i], 0) ; //Forcing main thread to main until these thread complete 
    } 
    pthread_mutex_destroy(&lock) ; //Destroying lock object 
} 



//compile this program using -lpthread option with g++ 
//g++ thread.cc -lpthread 
Cuestiones relacionadas