Motivação: o motivo pelo qual estou considerando é que meu gerente de projeto genial acha que o impulso é outra dependência e que é horrível porque "você depende dele" (tentei explicar a qualidade do impulso e desisti depois de algum tempo :( A menor razão pela qual eu gostaria de fazer isso é que eu gostaria de aprender os recursos do c ++ 11, porque as pessoas começarão a escrever código nele.
- Existe um mapeamento 1: 1 entre
#include<thread> #include<mutex>
e equivalentes de impulso? - Você consideraria uma boa idéia substituir o material de impulso pelo material do c ++ 11
. Meu uso é primitivo, mas há exemplos em que o std não oferece o que o impulso faz? Ou (blasfêmia) vice-versa?
PS Eu uso o GCC para que os cabeçalhos estejam lá.
Respostas:
Existem várias diferenças entre o Boost.Thread e a biblioteca de threads padrão do C ++ 11:
std::async
, mas o Boost nãoboost::shared_mutex
bloqueio para múltiplos leitores / gravador único. O análogostd::shared_timed_mutex
está disponível apenas desde C ++ 14 ( N3891 ), enquantostd::shared_mutex
está disponível apenas desde C ++ 17 ( N4508 ).boost::unique_future
vsstd::future
)std::thread
é diferente deboost::thread
--- Boost usaboost::bind
, o que requer argumentos copiáveis.std::thread
permite que tipos somente de movimentaçãostd::unique_ptr
sejam passados como argumentos. Devido ao uso deboost::bind
, a semântica de espaços reservados, como_1
em expressões de ligação aninhadas, também pode ser diferente.join()
oudetach()
oboost::thread
operador destruidor e de atribuição chamarádetach()
o objeto de thread que está sendo destruído / atribuído. Com umstd::thread
objeto C ++ 11 , isso resultará em uma chamadastd::terminate()
e abortará o aplicativo.Para esclarecer o ponto sobre os parâmetros somente de movimentação, o C ++ 11 válido é válido e transfere a propriedade do parâmetro
int
temporáriostd::unique_ptr
para o def1
quando o novo encadeamento é iniciado. No entanto, se você usarboost::thread
, ele não funcionará, pois é usadoboost::bind
internamente estd::unique_ptr
não pode ser copiado. Também existe um bug na biblioteca de threads C ++ 11 fornecida com o GCC que impede esse trabalho, como também é usadostd::bind
na implementação.Se você estiver usando o Boost, provavelmente poderá alternar para os threads do C ++ 11 de maneira relativamente indolor, se o seu compilador suportar (por exemplo, versões recentes do GCC no linux têm uma implementação quase completa da biblioteca de threads do C ++ 11 disponível no
-std=c++0x
modo).Se o seu compilador não suportar threads C ++ 11, você poderá obter uma implementação de terceiros como Just :: Thread , mas isso ainda é uma dependência.
fonte
lock
/unlock
para gravadores versus 'lock_shared / unlock_shared' para leitores). Vários leitores podem chamar o lock_shared sem bloquear, desde que nenhum gravador o esteja usando.shared_mutex
documentos estão em boost.org/doc/libs/1_47_0/doc/html/thread/… . Você bloqueia o mutex como compartilhado ou exclusivo e, em seguida, usa a função de desbloqueio correspondente. Você também pode usar os tipos RAII para fazer isso (shared_lock
usa um bloqueio de leitura compartilhadolock_guard
eunique_lock
um bloqueio exclusivo). Tentei esclarecer o ponto sobre os tipos somente de movimento.try_scoped_lock
funcionalidade é coberta porstd::unique_lock
. Existe um construtor que pega um mutex estd::try_to_lock
, em seguida, chamatry_lock()
o mutex em vez delock()
. Veja stdthread.co.uk/doc/headers/mutex/unique_lock/…std::thread
é amplamente modelado depoisboost::thread
, com algumas diferenças :Como é de 2007, alguns pontos não são mais válidos: agora
boost::thread
tem umanative_handle
função e, como comentam os comentaristas,std::thread
não tem mais cancelamento.Não encontrei diferenças significativas entre
boost::mutex
estd::mutex
.fonte
std::thread
não tem cancelamento; é issoboost::thread
que faz!interrupt()
aumentar o impulso :: thread? Também parece que é uma proposta original, o que mudou desde 2007.Há um motivo para não migrar para
std::thread
.Se você estiver usando vinculação estática,
std::thread
ficará inutilizável devido a esses bugs / recursos do gcc:Ou seja, se você ligar
std::thread::detach
oustd::thread::join
isso levará a uma exceção ou falha, enquantoboost::thread
funciona bem nesses casos.fonte
libpthread.a
. Você tem certeza absoluta do que está dizendo?Wl,--whole-archive -lpthread -Wl,--no-whole-archive
, consulte esta resposta, por exemplo, stackoverflow.com/a/23504509/72178 . Mas não é uma maneira muito direta de se conectarlibpthread.a
e também é considerada uma má ideia.Caso da empresa
Se você está escrevendo um software para a empresa que precisa ser executado em uma variedade de sistemas operacionais de moderada a grande e, consequentemente, compilado com uma variedade de compiladores e versões de compilador (especialmente os relativamente antigos) nesses sistemas operacionais, minha sugestão é ficar longe de C ++ 11 completamente por enquanto. Isso significa que você não pode usar
std::thread
, e eu recomendaria usarboost::thread
.Caso de Inicialização Básico / Técnico
Se você está escrevendo para um ou dois sistemas operacionais, sabe com certeza que só precisará construir com um compilador moderno que suporte principalmente C ++ 11 (por exemplo, VS2015, GCC 5.3, Xcode 7), e você ainda não está dependente da biblioteca de impulso,
std::thread
pode ser uma boa opção.Minha experiência
Pessoalmente, sou parcial em relação a bibliotecas robustas, usadas, altamente compatíveis e altamente consistentes, como impulso versus uma alternativa muito moderna. Isto é especialmente verdade para assuntos de programação complicados, como threading. Além disso, há muito tempo tenho tido grande sucesso com
boost::thread
(e otimização em geral) em uma vasta gama de ambientes, compiladores, modelos de encadeamento etc. Quando é minha opção, escolho a otimização.fonte
Com o Visual Studio 2013, o
std::mutex
comportamento parece diferente do que oboost::mutex
, o que me causou alguns problemas (consulte esta pergunta ).fonte
Com relação ao std :: shared_mutex adicionado no C ++ 17
As outras respostas aqui fornecem uma visão geral muito boa das diferenças em geral. No entanto, existem vários problemas com
std::shared_mutex
esse impulso resolvido.Mutices atualizáveis. Estes estão ausentes
std::thread
. Eles permitem que um leitor seja atualizado para um escritor sem permitir que outros escritores entrem antes de você . Isso permite que você faça coisas como pré-processar uma computação grande (por exemplo, reindexar uma estrutura de dados) quando estiver no modo de leitura e, em seguida, atualizar para gravar para aplicar a reindexação, mantendo apenas o bloqueio de gravação por um curto período de tempo.Justiça. Se você tiver atividade constante de leitura com a
std::shared_mutex
, seus escritores serão bloqueados indefinidamente. Isso ocorre porque, se outro leitor aparecer, ele sempre terá prioridade. Comboost:shared_mutex
, todos os threads eventualmente terão prioridade. (1) Nem leitores nem escritores passarão fome.O principal é que, se você tiver um sistema de alto rendimento, sem tempo de inatividade e contenção muito alta,
std::shared_mutex
nunca funcionará para você sem criar manualmente um sistema prioritário sobre ele.boost::shared_mutex
funcionará imediatamente, embora seja necessário mexer com ele em alguns casos. Eu argumentaria questd::shared_mutex
o comportamento é um bug latente que está esperando para acontecer na maioria dos códigos que o usam.(1) O algoritmo real usado é baseado no agendador de threads do SO. Na minha experiência, quando as leituras estão saturadas, há pausas mais longas (ao obter um bloqueio de gravação) no Windows do que no OSX / Linux.
fonte
Tentei usar o shared_ptr do std em vez do boost e encontrei um bug na implementação do gcc dessa classe. Meu aplicativo estava travando por causa do destruidor chamado duas vezes (essa classe deve ser segura para threads e não deve gerar esses problemas). Depois de passar para boost :: shared_ptr, todos os problemas desapareceram. As implementações atuais do C ++ 11 ainda não estão maduras.
O Boost também possui mais recursos. Por exemplo, o cabeçalho na versão std não fornece serializador para um fluxo (ou seja, cout << duration). O Boost possui muitas bibliotecas que usam seus próprios equivalentes etc., mas não cooperam com as versões std.
Para resumir - se você já possui um aplicativo escrito usando boost, é mais seguro manter seu código como está, em vez de se esforçar para mudar para o padrão C ++ 11.
fonte
shared_ptr
destruidor não precisa ser seguro para threads, é um comportamento indefinido ter um thread acessando um objeto enquanto outro thread o está destruindo. Se você acha que encontrou um bug no shared_ptr do GCC, informe -o , caso contrário, quanto à probabilidade de usá-lo errado.