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_mutex
bloqueo de lector múltiple / escritor único. El análogostd::shared_timed_mutex
está disponible solo desde C ++ 14 ( N3891 ), mientras questd::shared_mutex
está disponible solo desde C ++ 17 ( N4508 ).boost::unique_future
vsstd::future
)std::thread
es diferente deboost::thread
--- Usos de refuerzoboost::bind
, que requiere argumentos copiables.std::thread
permite que los tipos de solo movimientostd::unique_ptr
se pasen como argumentos. Debido al uso deboost::bind
, la semántica de los marcadores de posición, como_1
en las expresiones de enlace anidadas, también puede ser diferente.join()
odetach()
elboost::thread
destructor y el operador de asignación llamarándetach()
al objeto de hilo que se destruye / asigna. Con unstd::thread
objeto 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
int
lo temporalstd::unique_ptr
al parámetro def1
cuándo se inicia el nuevo hilo. Sin embargo, si lo usaboost::thread
, no funcionará, ya que se usaboost::bind
internamente ystd::unique_ptr
no 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::bind
en 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++0x
modo).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
/unlock
para 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_mutex
documentos 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_lock
toma un bloqueo de lectura compartidolock_guard
yunique_lock
toma un bloqueo exclusivo). He tratado de aclarar el punto sobre los tipos de solo movimiento.try_scoped_lock
funcionalidad 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::thread
está 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::thread
tiene unanative_handle
función ahora y, como señalan los comentaristas,std::thread
ya no tiene cancelación.No pude encontrar diferencias significativas entre
boost::mutex
ystd::mutex
.fuente
std::thread
no tiene cancelación; es loboost::thread
que 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::thread
queda inutilizable debido a estos errores / características de gcc:Es decir, si llama
std::thread::detach
ostd::thread::join
provocará una excepción o un bloqueo, mientrasboost::thread
funciona 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.a
y 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::thread
podrí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::mutex
parece 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_mutex
ese 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_mutex
nunca funcionará para usted sin construir manualmente un sistema prioritario sobre él.boost::shared_mutex
funcionará de la caja, aunque es posible que deba modificarlo en ciertos casos. Yo diría questd::shared_mutex
el 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_ptr
destructor 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.