Saltar al contenido

¿Es inteligente reemplazar boost :: thread y boost :: mutex con equivalentes de c ++ 11?

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álogo std::shared_timed_mutex está disponible solo desde C ++ 14 (N3891), mientras que std::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 vs std::future)
  • La semántica de paso de argumentos de std::thread son diferentes a boost::thread — Impulsar usos boost::bind, que requiere argumentos copiables. std::thread permite tipos de solo movimiento como std::unique_ptr para pasar como argumentos. Debido al uso de boost::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() o detach() entonces el boost::thread el destructor y el operador de asignación llamarán detach() en el objeto de hilo que se está destruyendo / asignando. Con un C ++ 11 std::thread objeto, esto resultará en una llamada a std::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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *