Boost::线程函数导致嵌入式ARM上的分段故障
Boost::Thread function leading to a segmentation fault on an embedded ARM
我在使用Boost::threads的线程类中遇到了一个奇怪的问题。以下是我正在做的事情的简要总结:
例程创建一组对象,这些对象由具有私有数据成员的处理程序类组成,该私有数据成员是指向基类的共享指针,该基类形成继承树。我很有信心这个程序是正确的,而不是问题的一部分。
然后,我调用处理程序类(startUpdate)的一个方法,该方法将创建我的线程类的一个新实例。这是线程类代码:
class Sensor_Thread
{
public:
//constructor (creates thread and binds the update function to it
Sensor_Thread (const Ptr<Sensor_Base> & theSensor): m_stoprequested (false),
s (theSensor),
m_thread (boost::bind (&Sensor_Thread::update, this)) { }
//default null constructor, shouldn't ever be used
Sensor_Thread (): m_stoprequested (true),
m_thread (),
s (NULL) { }
//destructor (automatically joins the thread as per RAII principles)
~Sensor_Thread () { m_stoprequested = true; m_thread.join (); }
private:
volatile bool m_stoprequested;
boost::mutex m_mutex;
boost::thread m_thread;
Ptr<Sensor_Base> s;
void update ();
};
("Ptr"类是我的共享指针类……我很有信心它能正确工作,因为我最初是从C++教科书中得到的……)
更新功能:
void Sensor_Thread::update ()
{
//make sure we actually have a sensor attached...
if (s) {
// set up structure for sleeping
struct timespec time;
while (!m_stoprequested)
{
boost::mutex::scoped_lock lock(m_mutex);
s->update ();
time.tv_sec = s->updateInterval / 1000;
time.tv_nsec = (1000 % s->updateInterval) * (1000 * 1000);
nanosleep (&time, NULL);
}
}
}
这将无限期运行,直到驱动程序中的另一个触发器调用stopUpdate并且threaded_class被销毁。
奇怪之处:在我的OS X 10.6开发盒上,使用darwin gcc 4.2.1,它运行良好,完全符合预期。
这意味着在使用debian-linux和ARM处理器的嵌入式服务器上运行。我有一个由嵌入式系统制造商提供的交叉编译工具链,当我使用它进行交叉编译时,我会得到一个seg错误。通过调试,我发现这个seg错误发生在调用s->update()时(或者任何其他试图取消引用共享指针并对其执行操作的尝试)。然而,如果我引入了一个轻微的延迟,比如在Sensor_Thread::update函数中启动while循环之前添加"sleep(1);",它可以完美地工作。
在我看来,这似乎意味着系统试图在完全或充分初始化之前取消引用共享指针s?sleep(1)的变通方法使它能够工作,但对我来说,这似乎非常奇怪。如果线程类的共享指针在构造函数期间初始化,那么在调用更新函数之前,它不应该准备好吗?或者boost::thread的创建是否意味着更新函数与线程类所拥有的共享指针的初始化同时发生?有没有比"睡眠"破解更干净的方法来确保在调用更新函数之前初始化共享指针?
谢谢!!!
Sensor_Thread (const Ptr<Sensor_Base> & theSensor): m_stoprequested (false),
s (theSensor),
m_thread (boost::bind (&Sensor_Thread::update, this)) { }
此代码已损坏。您正在对尚未构造的对象调用update
。在构造函数的初始化列表中使用this
应该始终引发一个红色标志。它是指向一个尚未完全存在的对象的指针。
通常的处理方法是将其分为两个步骤。使用run
或start
方法创建线程。在构造函数返回后调用该方法。
while (!m_stoprequested)
{
boost::mutex::scoped_lock lock(m_mutex);
s->update ();
time.tv_sec = s->updateInterval / 1000;
time.tv_nsec = (1000 % s->updateInterval) * (1000 * 1000);
nanosleep (&time, NULL);
}
这可能不是你想要的。它总是保持互斥,使得另一个线程很难访问s
。它必须等到下一次更新,然后才能赢得互斥锁的竞争。在一些平台上,一个正在进行实际工作的线程将很难击败一个"交互式"线程(一个主要是睡眠的线程)。因此,这可能会使试图访问s
的任何其他线程的速度大大减慢。
为什么在持有互斥对象的情况下调用nanosleep
?
- 分段故障(堆芯转储)矢量
- C++中的动态铸造故障
- 数组的指针从不分段故障
- vscode g++链路故障:体系结构x86_64的未定义符号
- 访问被拒绝后,c++中的故障保护代码
- Windows 10-使用gtkmm-3.0库和g++[包括再现]的分段故障
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 调试 CUDA MMU 故障
- 海湾合作委员会 ARM 性能下降
- Geeksforgeeks C 程序故障排除:IEE 754 表示法为十进制
- Arch Linux.AUR 包 mysql 不能用 makepkg 构建.错误:构建 () 中出现故障
- 如何在带有 gdb GUI 前端的 ARM gdbserver 的 PC 上执行远程 gdb 会话?
- 正在处理故障(堆芯转储)
- 在 Boost::fiber 中引发的BOOST_ASSERT故障 Visual Studio "Debug" 构建
- 如何进行故障排除:未定义对"非虚拟 thunk to ..."的引用
- C/C++ 字符串错误与 ARM SEG 故障总线错误
- 为什么在 32 位 ARM 平台上为 SIGSEGV 0x00000006故障地址
- 来自 ARM 皮层 M0 NRF51822 上的硬故障处理程序的 GDB 回溯
- Boost::线程函数导致嵌入式ARM上的分段故障
- 使用arm-linux- gnuabi -g++ -o时出现段故障,不使用-o也不会出现问题