Motivación: la razón por la que lo estoy considerando es que mi genio gerente de proyecto piensa que el impulso es otra dependencia y que es horrible porque "usted depende de él" (intenté explicar la calidad del impulso, y luego me di por vencido después de un tiempo :( La razón más pequeña por la que me gustaría hacerlo es que me gustaría aprender las características de c ++ 11, porque la gente comenzará a escribir código en él.
- ¿Existe un mapeo 1: 1 entre
#include<thread> #include<mutex>y equivalentes de impulso? - ¿Consideraría una buena idea reemplazar las cosas de impulso con cosas de c ++ 11
? Mi uso es primitivo, pero ¿hay ejemplos cuando std no ofrece qué impulso? O (blasfemia) viceversa?
PD: uso GCC, así que los encabezados están ahí.

Respuestas:
Existen varias diferencias entre Boost.Thread y la biblioteca de hilos estándar C ++ 11:
std::async, pero Boost noboost::shared_mutexbloqueo de lector múltiple / escritor único. El análogostd::shared_timed_mutexestá disponible solo desde C ++ 14 ( N3891 ), mientras questd::shared_mutexestá disponible solo desde C ++ 17 ( N4508 ).boost::unique_futurevsstd::future)std::threades diferente deboost::thread--- Usos de refuerzoboost::bind, que requiere argumentos copiables.std::threadpermite que los tipos de solo movimientostd::unique_ptrse pasen como argumentos. Debido al uso deboost::bind, la semántica de los marcadores de posición, como_1en las expresiones de enlace anidadas, también puede ser diferente.join()odetach()elboost::threaddestructor y el operador de asignación llamarándetach()al objeto de hilo que se destruye / asigna. Con unstd::threadobjeto C ++ 11 , esto dará como resultado una llamada astd::terminate()y anulará la aplicación.Para aclarar el punto sobre los parámetros de solo movimiento, lo siguiente es válido C ++ 11, y transfiere la propiedad de
intlo temporalstd::unique_ptral parámetro def1cuándo se inicia el nuevo hilo. Sin embargo, si lo usaboost::thread, no funcionará, ya que se usaboost::bindinternamente ystd::unique_ptrno se puede copiar. También hay un error en la biblioteca de subprocesos C ++ 11 proporcionada con GCC que impide que esto funcione, ya que también se usastd::binden la implementación allí.Si está utilizando Boost, entonces probablemente pueda cambiar a subprocesos de C ++ 11 sin problemas si su compilador lo admite (por ejemplo, las versiones recientes de GCC en Linux tienen una implementación casi completa de la biblioteca de subprocesos de C ++ 11 disponible en
-std=c++0xmodo).Si su compilador no admite subprocesos de C ++ 11, puede obtener una implementación de terceros como Just :: Thread , pero esto sigue siendo una dependencia.
fuente
lock/unlockpara escritores vs. 'lock_shared / unlock_shared' para lectores). Múltiples lectores pueden llamar a lock_shared sin bloquear, siempre y cuando ningún escritor lo esté usando.shared_mutexdocumentos están en boost.org/doc/libs/1_47_0/doc/html/thread/… . Puede bloquear el mutex como compartido o exclusivo, y luego usar la función de desbloqueo correspondiente. También puede usar los tipos RAII para hacer esto (shared_locktoma un bloqueo de lectura compartidolock_guardyunique_locktoma un bloqueo exclusivo). He tratado de aclarar el punto sobre los tipos de solo movimiento.try_scoped_lockfuncionalidad está cubierta porstd::unique_lock. Hay un constructor que toma un mutex ystd::try_to_lock, y luego llamarátry_lock()al mutex en lugar delock(). Ver stdthread.co.uk/doc/headers/mutex/unique_lock/…std::threadestá modelado en gran parte despuésboost::thread, con algunas diferencias :Esto es de 2007, por lo que algunos puntos ya no son válidos:
boost::threadtiene unanative_handlefunción ahora y, como señalan los comentaristas,std::threadya no tiene cancelación.No pude encontrar diferencias significativas entre
boost::mutexystd::mutex.fuente
std::threadno tiene cancelación; es loboost::threadque hace!interrupt()a boost :: thread? También parece que es una propuesta original, que cambió desde 2007.Hay una razón para no migrar
std::thread.Si está utilizando enlaces estáticos,
std::threadqueda inutilizable debido a estos errores / características de gcc:Es decir, si llama
std::thread::detachostd::thread::joinprovocará una excepción o un bloqueo, mientrasboost::threadfunciona bien en estos casos.fuente
libpthread.a. ¿Estás absolutamente seguro de lo que estás diciendo?Wl,--whole-archive -lpthread -Wl,--no-whole-archive, vea esta respuesta, por ejemplo stackoverflow.com/a/23504509/72178 . Pero no es una forma muy directa de vincularselibpthread.ay también se considera una mala idea.Caso empresarial
Si está escribiendo software para la empresa que necesita ejecutarse en una variedad moderada a grande de sistemas operativos y, en consecuencia, construir con una variedad de compiladores y versiones de compiladores (especialmente los relativamente antiguos) en esos sistemas operativos, mi sugerencia es mantenerse alejado de C ++ 11 en total por ahora. Eso significa que no puede usar
std::thread, y recomendaría usarboost::thread.Funda Básica / Tech Startup
Si está escribiendo para uno o dos sistemas operativos, sabe con certeza que solo necesitará compilar con un compilador moderno que sea compatible principalmente con C ++ 11 (por ejemplo, VS2015, GCC 5.3, Xcode 7), y aún no lo ha hecho. dependiendo de la biblioteca de impulso, entonces
std::threadpodría ser una buena opción.Mi experiencia
Personalmente, soy partidario de las bibliotecas reforzadas, muy utilizadas, altamente compatibles y altamente consistentes, como boost versus una alternativa muy moderna. Esto es especialmente cierto para temas de programación complicados como el enhebrado. Además, durante mucho tiempo he experimentado un gran éxito con
boost::thread(y boost en general) en una amplia gama de entornos, compiladores, modelos de subprocesos, etc. Cuando es mi elección, elijo boost.fuente
Con Visual Studio 2013,
std::mutexparece que se comporta de manera diferente que elboost::mutex, lo que me causó algunos problemas (vea esta pregunta ).fuente
Con respecto a std :: shared_mutex agregado en C ++ 17
Las otras respuestas aquí proporcionan una muy buena visión general de las diferencias en general. Sin embargo, hay varios problemas con
std::shared_mutexese impulso resuelve.Muticios actualizables. Estos están ausentes de
std::thread. Permiten que un lector se actualice a escritor sin permitir que otros escritores entren antes que usted . Estos le permiten hacer cosas como preprocesar un gran cálculo (por ejemplo, reindexar una estructura de datos) cuando está en modo de lectura, luego actualizar para escribir para aplicar el reindex mientras mantiene presionado el bloqueo de escritura por un corto tiempo.Justicia. Si tiene actividad de lectura constante con a
std::shared_mutex, sus escritores estarán bloqueados indefinidamente. Esto se debe a que si aparece otro lector, siempre se les dará prioridad. Conboost:shared_mutex, todos los hilos eventualmente tendrán prioridad. (1) Ni los lectores ni los escritores estarán hambrientos.El problema de esto es que si tiene un sistema de alto rendimiento sin tiempo de inactividad y una contención muy alta,
std::shared_mutexnunca funcionará para usted sin construir manualmente un sistema prioritario sobre él.boost::shared_mutexfuncionará de la caja, aunque es posible que deba modificarlo en ciertos casos. Yo diría questd::shared_mutexel comportamiento es un error latente que espera suceder en la mayoría de los códigos que lo usan.(1) El algoritmo real que utiliza se basa en el programador de subprocesos del sistema operativo. En mi experiencia, cuando las lecturas están saturadas, hay pausas más largas (al obtener un bloqueo de escritura) en Windows que en OSX / Linux.
fuente
Intenté usar shared_ptr desde std en lugar de boost y de hecho encontré un error en la implementación de gcc de esta clase. Mi aplicación se bloqueó debido a que el destructor se llamó dos veces (esta clase debería ser segura para subprocesos y no debería generar tales problemas). Después de mover para impulsar :: shared_ptr todos los problemas desaparecieron. Las implementaciones actuales de C ++ 11 aún no están maduras.
Boost también tiene más características. Por ejemplo, el encabezado en la versión estándar no proporciona el serializador a una secuencia (es decir, cout << duración). Boost tiene muchas bibliotecas que usan sus propios equivalentes, etc., pero no cooperan con las versiones estándar.
En resumen: si ya tiene una aplicación escrita con boost, es más seguro mantener su código tal como está en lugar de esforzarse para pasar al estándar C ++ 11.
fuente
shared_ptrdestructor no necesita ser seguro para subprocesos, es un comportamiento indefinido que un subproceso acceda a un objeto mientras otro subproceso lo está destruyendo. Si cree que ha encontrado un error en shared_ptr de GCC, infórmelo, de lo contrario, en el balance de probabilidad, lo está usando mal.