Application boost:: поток застрял на блокировке мьютекса при компиляции для ARM, работающей на BeagleBone Black


В настоящее время я работаю над приложением C++, которое отлично работает на моем ПК, и я хочу, чтобы оно работало на BeagleBone Black, на котором я уже установил Debian Wheezy.

Я соберу крест, используя ELDK У5.3 и qmake из Мой компьютер (Intel Celeron с, Debian хриплый, повысить В1.49.0-3.2) для BeagleBone черный (рукоятки Коркы A8, Debian хриплый, повысить В1.49.0-3.2).

Все работает так, как должно, но время от времени мое приложение зависает (застревает на__pthread _ mutex _ lock), когда импульс::создаваемый поток или приложение ждет повышение::тема::присоединиться(). Я просто хочу понять, что происходит.

Если у вас есть несколько советов, которые могут помочь мне защитить эти вызовы boost::thread (try/catch, error status check ...) пожалуйста, поделитесь ими :)

Спасибо !!

Вот небольшой исходный код, который замерзает аналогичным образом при выполнении на BeagleBone Black, за которым следует backtrace, напечатанный при замораживании приложения (GDB) и файл. pro, используемый при выполнении команда qmake:

#include <stdio.h>
#include <boost/thread.hpp>

#define NB_THREADS              20
#define THREAD_LIFE_DURATION    5

int g_nb_thread = 0;

boost::thread * subRegisterThread(boost::thread * pthread)
{
    printf("Register thread #%d  %p createdn",
        g_nb_thread++, pthread);

    return pthread;
}

/////////////////// Sub dummy class

class sub_dummy_class
{
public:
    boost::thread *mThread;

    sub_dummy_class();
    ~sub_dummy_class();
    void loop();
    void start();
};



sub_dummy_class::sub_dummy_class()
{
    mThread = NULL;
}

sub_dummy_class::~sub_dummy_class()
{
    if(mThread)
    {
        mThread->join();
    }
}

void sub_dummy_class::start()
{
    mThread = subRegisterThread(new boost::thread(boost::bind(&sub_dummy_class::loop, this)));
}

void sub_dummy_class::loop()
{
    int life_duration = THREAD_LIFE_DURATION;
    while(life_duration > 0)
    {
        life_duration--;
        printf("Got %d seconds to live !n", life_duration);
        usleep(1000000);
    }
    return;
}


////////////////////////// Dummy class

class dummy_class
{
public:

    sub_dummy_class dummies[NB_THREADS];

    dummy_class();
    ~dummy_class();
    void start();


};

dummy_class::dummy_class()
{

}

dummy_class::~dummy_class()
{

}

void dummy_class::start()
{
    for(int i = 0 ; i < NB_THREADS ; i++)
    {
        dummies[i].start();
    }
}


int main(int argc, char* argv[])
{
    printf("Starting programn");

    printf("Creating dummy classn");
    dummy_class *DC = new dummy_class();

    printf("Starting dummy classn");
    DC->start();

    printf("Deleting dummy classn");
    delete DC;

    return 0;
}

Трассировка стека:

(gdb) bt
#0  __libc_do_syscall () at ../ports/sysdeps/unix/sysv/linux/arm/eabi/libc-do-syscall.S:44
#1  0xb6756f92 in __lll_lock_wait (futex=0x1881c, private=0) at ../ports/sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c:47
#2  0xb675357a in __pthread_mutex_lock (mutex=0x1881c) at pthread_mutex_lock.c:61
#3  0xb68029dc in pthread_mutex_lock (mutex=<optimized out>) at forward.c:182
#4  0xb6991710 in lock (this=0xb69a2c68) at ./boost/smart_ptr/detail/spinlock_pt.hpp:41
#5  scoped_lock (pv=0x1f714, this=<synthetic pointer>) at ./boost/smart_ptr/detail/spinlock_pool.hpp:65
#6  atomic_increment (pw=0x1f714) at ./boost/smart_ptr/detail/sp_counted_base_spin.hpp:41
#7  add_ref_copy (this=0x1f710) at ./boost/smart_ptr/detail/sp_counted_base_spin.hpp:90
#8  shared_count (r=..., this=<optimized out>) at ./boost/smart_ptr/detail/shared_count.hpp:316
#9  shared_ptr (this=<optimized out>) at ./boost/smart_ptr/shared_ptr.hpp:164
#10 operator= (r=..., this=0x1f604) at ./boost/smart_ptr/shared_ptr.hpp:311
#11 boost::thread::start_thread (this=0x1f5e8) at libs/thread/src/pthread/thread.cpp:185
#12 0x0000cf7c in boost::thread::thread<boost::_bi::bind_t<void, boost::_mfi::mf0<void, sub_dummy_class>, boost::_bi::list1<boost::_bi::value<sub_dummy_class*> > > > (this=0x1f5e8, f=...)
    at /opt/eldk-5.3/armv7a-hf/sysroots/armv7ahf-vfp-neon-linux-gnueabi/usr/include/boost/thread/detail/thread.hpp:205
#13 0x0000aa44 in sub_dummy_class::start (this=0x1cfdc) at main.cpp:51
#14 0x0000abc4 in dummy_class::start (this=0x1cf90) at main.cpp:96
#15 0x0000ac44 in main (argc=1, argv=0xbefff834) at main.cpp:109

EDIT: вот файл. pro, который я использую для команды qmake (qmake-spec linux-armv7a-hf-g++):

# .pro for test_boost
TEMPLATE = app
CONFIG =

QT -= qt webkit

TARGET = test_boost_ARM
QMAKE_LFLAGS += -Wl,-rpath ./
QMAKE_LFLAGS_RPATH =

HEADERS =
SOURCES = main.cpp

OTHER_FILES =

DESTDIR = .

# external libs
LIBS += -lboost_thread

Я немного проверил эти два параметра. Когда NB_THREADS=15, кажется, что все идет нормально каждый раз, но когда он равен 16, он часто замирает. THREAD_LIFE_DURATION, похоже, не оказывает никакого влияния на поведение программы. Я надеюсь, что это поможет кому-то понять, что происходит.

1 3

1 ответ:

Похоже, что обновление boost до версии 1.54 исправляет эту проблему. Потребовалось некоторое время, чтобы получить правильные пакеты, потому что Debian Wheezy boost stable release 1.49, поэтому мне пришлось вручную обновить свою платформу кросс-компиляции.

Приложение теперь может работать до 380 потоков без каких-либо проблем, это более чем достаточно для меня.