Solución:
Hay varias diferencias entre Boost.Thread y la biblioteca de subprocesos estándar C ++ 11:
- Boost admite la cancelación de subprocesos, los subprocesos de C ++ 11 no
- Soporta C ++ 11
std::async
, pero Boost no - Boost tiene un
boost::shared_mutex
para 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). - Los tiempos de espera de C ++ 11 son diferentes a los tiempos de espera de Boost (aunque esto debería cambiar pronto ahora que se ha aceptado Boost.Chrono).
- Algunos de los nombres son diferentes (p. Ej.
boost::unique_future
vsstd::future
) - La semántica de paso de argumentos de
std::thread
son diferentes aboost::thread
— Impulsar usosboost::bind
, que requiere argumentos copiables.std::thread
permite tipos de solo movimiento comostd::unique_ptr
para pasar como argumentos. Debido al uso deboost::bind
, la semántica de marcadores de posición como_1
en las expresiones de vinculación anidadas también pueden ser diferentes. - Si no llamas explícitamente
join()
odetach()
entonces elboost::thread
el destructor y el operador de asignación llamarándetach()
en el objeto de hilo que se está destruyendo / asignando. Con un C ++ 11std::thread
objeto, esto resultará en una llamada astd::terminate()
y abortar la aplicación.
Para aclarar el punto sobre los parámetros de solo movimiento, lo siguiente es C ++ 11 válido y transfiere la propiedad del int
de lo temporal std::unique_ptr
al parámetro de f1
cuando se inicia el nuevo hilo. Sin embargo, si usa boost::thread
entonces no funcionará, ya que usa boost::bind
internamente, y std::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 usa std::bind
en la implementación allí también.
void f1(std::unique_ptr<int>);
std::thread t1(f1,std::unique_ptr<int>(new int(42)));
Si está utilizando Boost, probablemente pueda cambiar a los subprocesos de C ++ 11 con relativa facilidad 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, es posible que pueda obtener una implementación de terceros como Just :: Thread, pero esto sigue siendo una dependencia.
std::thread
se modela en gran medida a partir de boost::thread
, con algunas diferencias:
- La semántica de boost no se puede copiar, one-handle-maps-to-one-os-thread, se retiene. Pero este hilo se puede mover para permitir devolver el hilo de las funciones de fábrica y colocarlo en contenedores.
- Esta propuesta agrega la cancelación a la
boost::thread
, que es una complicación importante. Este cambio tiene un gran impacto no solo en el subproceso, sino también en el resto de la biblioteca de subprocesos de C ++. Se cree que este gran cambio se justifica debido al beneficio.
- El destructor de subprocesos ahora debe llamar a cancelar antes de desconectar para evitar filtrar accidentalmente los subprocesos secundarios cuando se cancelan los subprocesos principales.
- Ahora se requiere un miembro de separación explícito para habilitar la separación sin cancelar.
- Los conceptos de identificador de subproceso e identidad de subproceso se han separado en dos clases (son la misma clase en
boost::thread
). Esto es para facilitar la manipulación y el almacenamiento de la identidad del hilo.- Se ha agregado la capacidad de crear un ID de subproceso que se garantiza que se comparará con ningún otro subproceso que se pueda unir (
boost::thread
no tiene esto). Esto es útil para el código que quiere saber si está siendo ejecutado por el mismo hilo que una llamada anterior (los mutex recursivos son un ejemplo concreto).- Existe una “puerta trasera” para obtener el identificador de subprocesos nativos para que los clientes puedan manipular subprocesos utilizando el sistema operativo subyacente si así lo desean.
Esto es de 2007, por lo que algunos puntos ya no son válidos: boost::thread
tiene un native_handle
funcionan ahora y, como señalan los comentaristas, std::thread
ya no tiene cancelación.
No pude encontrar ninguna diferencia significativa entre boost::mutex
y std::mutex
.
Caso empresarial
Si está escribiendo software para la empresa que necesita ejecutarse en una variedad de sistemas operativos de moderada a grande y, en consecuencia, compilar 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 puedes usar std::thread
, y recomendaría usar boost::thread
.
Caso de inicio básico / tecnológico
Si está escribiendo para uno o dos sistemas operativos, sabe con certeza que solo necesitará compilar con un compilador moderno que admita principalmente C ++ 11 (por ejemplo, VS2015, GCC 5.3, Xcode 7), y aún no lo ha hecho. depende de la biblioteca de impulso, entonces std::thread
podría ser una buena opción.
Mi experiencia
Personalmente, soy partidario de bibliotecas reforzadas, muy utilizadas, altamente compatibles y muy consistentes, como boost frente a 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.