Вопрос

Я пытаюсь написать довольно простое потоковое приложение, но я новичок в библиотеке потоков boost.Простая тестовая программа, над которой я работаю, это:

#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;
}

Однако, когда я компилирую и запускаю эту программу, я получаю вывод

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

Очевидно, что результат правильный, но меня беспокоит это сообщение об ошибке, особенно потому, что реальная программа, которая имеет по существу ту же структуру, застревает в точке join_all().Может кто-нибудь объяснить мне, что происходит?Есть ли лучший способ сделать это, т.е.запустить несколько потоков, сохранить их во внешнем контейнере, а затем дождаться их завершения, прежде чем продолжить программу?

Спасибо за вашу помощь.

Это было полезно?

Решение

Я думаю, что ваша проблема вызвана деструктором thread_group, который вызывается при выходе вашей программы.Thread group хочет взять на себя ответственность за уничтожение ваших объектов thread.Смотрите также в повышение::thread_group Документация.

Вы создаете свои объекты thread в стеке как локальные переменные в области вашей основной функции.Таким образом, они уже были уничтожены при выходе из программы и thread_group пытается их удалить.

В качестве решения создайте свои объекты thread в куче с помощью новое и пусть thread_group позаботится об их уничтожении:

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

Другие советы

Если вам не нужен дескриптор для ваших потоков, попробуйте использовать thread_group::create_thread(), что вообще устраняет необходимость управлять потоком:

// 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() становится владельцем потока, который вы передаете.Группа потоков удаляет поток.В этом примере вы удаляете память, выделенную в стеке, что в значительной степени является тяжким преступлением.

Функция - член add_thread() добавить поток()

аннулирует add_thread(поток * thrd);

Предварительное условие:

Выражение delete thrd является правильно сформированным и не приведет к неопределенному поведению.

Эффекты:

Возьмите на себя управление boost::thread объектом, на который указывает thrdи добавьте его в группу.

Постусловие:

this->size() увеличивается на единицу.

Не уверен, что именно в этом ошибка в вашем коде, или это просто пример ошибки.В остальном код выглядит нормально.

Похоже, ни один из вышеперечисленных вопросов на самом деле не ответил на этот вопрос.

Я столкнулся с аналогичной проблемой.Последствия этого предупреждения (pthread_mutex_lock.c:87:__pthread_mutex_lock _поток_мутекс_блокировка:Утверждение `мьютекс->_данные._owner == 0' сбой.Прервано) это то, что иногда программа пропустит потоки и вызовет исключение boost_resource_error.

Причина выглядит так, что программа продолжает выполняться после join_all(), хотя большинство потоков все еще запущены (не завершены ).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top