c++ - 为在 BeagleBone Black 上运行的 ARM 编译时,应用程序 boost::thread 卡在互斥锁上

标签 c++ locking cross-compiling boost-thread beagleboneblack

我目前正在开发一个在我的 PC 上运行良好的 C++ 应用程序,我想让它在我已经安装了 Debian Wheezy 的 BeagleBone Black 上运行。

我正在使用 ELDK v5.3 和 qmake 从我的 PC(Intel Celeron、Debian Wheezy、boost v1.49.0-3.2)交叉编译到 BeagleBone Black(ARM Cortex A8、Debian Wheezy、boost v1.49.0-3.2) ).

一切正常,但时不时地,当创建 boost::thread 或应用程序正在等待 boost::thread::join() 时,我的应用程序会卡住(卡在 __pthread_mutex_lock 上)。我只想了解发生了什么。

如果您有一些技巧可以帮助我保护这些对 boost::thread 的调用(try/catch、错误状态检查...),请分享它们:)

谢谢!!

这是一个小源代码,在 BeagleBone Black 上执行时以类似的方式卡住,然后是应用程序卡住时打印的回溯 (GDB) 和执行 qmake 命令时使用的 .pro 文件:

#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 created\n",
        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 program\n");

    printf("Creating dummy class\n");
    dummy_class *DC = new dummy_class();

    printf("Starting dummy class\n");
    DC->start();

    printf("Deleting dummy class\n");
    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

编辑:这是我用于 qmake 命令的 .pro 文件(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 似乎对程序的行为没有任何影响。我希望它能帮助人们理解发生了什么。

最佳答案

看来将 boost 升级到 1.54 版可以解决这个问题。花了一些时间来获得正确的软件包,因为 Debian Wheezy 的 boost 稳定版本是 1.49,所以我不得不手动升级我的交叉编译平台。

该应用现在可以毫无问题地运行多达 380 个线程,这对我来说已经足够了。

关于c++ - 为在 BeagleBone Black 上运行的 ARM 编译时,应用程序 boost::thread 卡在互斥锁上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18107163/

相关文章:

c++ - 如何使用 Qt/C++ 打开和显示 PDF 文件?

c++ - 我可以从具有不同数字分隔符的 istream 中读取 double 值吗?

python - 在 Python 中调用 exit() 时,C++ 析构函数中的互斥锁会导致异常

c# - 这把锁有什么问题?

linux - 设置 Go 进行交叉编译时出错

c++ - 公开定义对象,但在构造函数中创建它

c++ - 求解位方程

mysql - 在事务中锁定表

找不到-lpthread

linux - 如何从 Linux 环境交叉编译适用于 MacOS 的 R 包?