我目前正在开发一款在我的电脑上运行的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(尝试/捕获,错误状态检查...),请分享它们:)
谢谢!
这是一个小的源代码,当在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似乎对程序的行为没有任何影响。我希望它能帮助别人了解正在发生的事情。
答案 0 :(得分:1)
看起来升级版本1.54的升级解决了这个问题。花了一些时间来获得正确的软件包因为Debian Wheezy的稳定版本是1.49,所以我不得不手动升级我的交叉编译平台。
该应用程序现在可以运行多达380个线程而没有任何问题,这对我来说已经足够了。