Pergunta

Eu estou tentando escrever um aplicativo de rosca bastante simples, mas sou novo para a biblioteca thread de impulso. Um programa simples teste que estou trabalhando é:

#include <iostream>
#include <boost/thread.hpp>

int result = 0;
boost::mutex result_mutex;

boost::thread_group g;

void threaded_function(int i)
{
    for(; i < 100000; ++i) {}

    {
        boost::mutex::scoped_lock lock(result_mutex);
        result += i;
    }
}

int main(int argc, char* argv[])
{
    using namespace std;

    // launch three threads
    boost::thread t1(threaded_function, 10);
    boost::thread t2(threaded_function, 10);
    boost::thread t3(threaded_function, 10);

    g.add_thread(&t1);
    g.add_thread(&t2);
    g.add_thread(&t3);

    // wait for them
    g.join_all();

    cout << result << endl;

    return 0;
}

No entanto, quando eu compilar e executar este programa que eu obter uma saída de

$ ./test 
300000
test: pthread_mutex_lock.c:87: __pthread_mutex_lock: Assertion `mutex->__data.__owner == 0' failed.
Aborted

Obviamente, o resultado é correto, mas estou preocupado com esta mensagem de erro, especialmente porque o programa real, que tem essencialmente a mesma estrutura, está ficando preso no (ponto) join_all. Alguém pode me explicar o que está acontecendo? Existe uma maneira melhor de fazer isso, ou seja, lançar uma série de tópicos, armazená-los em um recipiente externo, e depois esperar por todos eles para completar antes de continuar o programa?

Obrigado por sua ajuda.

Foi útil?

Solução

Eu acho que você problema é causado pela destruição thread_group que é chamado quando da saída do programa. grupo Tópico quer assumir a responsabilidade da destruindo seus objetos de rosca. Veja também no boost :: thread_group documentação.

Você está criando seu segmento objetos na pilha como variáveis ??locais no âmbito da sua função principal. Assim, eles já foram destruídas quando o programa sai e thread_group tenta excluí-los.

Como uma solução, criar seus objetos de rosca na pilha com new e deixar o thread_group cuidar de sua destruição:

boost::thread *t1 = new boost::thread(threaded_function, 10);
...
g.add_thread(t1);
...

Outras dicas

Se você não precisa de um identificador para os seus tópicos, tente usar thread_group :: create_thread () que alivia a necessidade de gerenciar o fio em tudo:

// Snip: Same as previous examples

int main(int argc, char* argv[])
{
    using namespace std;

    // launch three threads
    for ( int i = 0; i < 3; ++i )
        g.create_thread( boost::bind( threaded_function, 10 ) );

    // wait for them
    g.join_all();

    cout << result << endl;

    return 0;
}

add_thread () toma posse de rosca você passar. Passe grupo exclui o segmento. Neste exemplo você está excluindo memória alocada na pilha, praticamente uma ofensa capital.

Função membro add_thread ()

vazio add_thread (thread * thrd);

Pré-requisito :

O thrd exclusão expressão é bem formado e não vai resultar em comportamento indefinido.

Efeitos:

Apropriar-se do boost :: fio objeto apontado por thrd e adicioná-lo para o grupo.

Pós-condição :

este-> tamanho () é aumentado por um.

Não tenho certeza se é isso que está errado no seu código, ou se isso é apenas exemplo bug. Caso contrário olhares de código bem.

Parece nenhum dos acima realmente respondeu à pergunta.

Eu conheci o problema semelhante. A consequência desta advertência (pthread_mutex_lock.c: 87: __pthread_mutex_lock: Declaração `mutex -> _ dados _owner == 0' falhou.. Aborted) é que às vezes o programa vai vazar tópicos e causar uma exceção boost_resource_error.

Os olhares razão como o programa continua a executar após join_all () embora a maioria dos tópicos ainda estão em execução (não terminado).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top