【发布时间】:2012-02-14 15:48:04
【问题描述】:
我在使用 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 处理器的嵌入式服务器上运行。我有一个嵌入式系统制造商提供的交叉编译工具链,当我使用它进行交叉编译时,我得到一个段错误。通过调试,我发现在调用 s->update () 时会发生此段错误(或任何其他尝试取消引用共享指针并对它执行某些操作)。但是,如果我引入一点延迟,比如添加“sleep(1);”在我的 Sensor_Thread::update 函数中开始 while 循环之前,它可以完美运行。
在我看来,这似乎暗示系统试图在共享指针 s 完全或充分初始化之前取消引用它? sleep(1) 变通方法使它工作,但是,这对我来说似乎非常奇怪。如果线程类的共享指针在构造函数期间被初始化,它不应该在更新函数被调用之前准备好吗?或者 boost::thread 的创建是否意味着更新函数与线程类拥有的共享指针的初始化同时发生?有没有比“sleep”更干净的方法来确保在调用更新函数之前初始化共享指针?
谢谢!!!
【问题讨论】:
-
您对教科书的信心令人着迷。 :)
标签: c++ multithreading boost segmentation-fault arm