【问题标题】:Why is std::queue.front() causing an segment fault? [closed]为什么 std::queue.front() 会导致段错误? [关闭]
【发布时间】:2017-06-23 16:54:06
【问题描述】:

场景如下: 我正在尝试使用 libev 编写一个简单的多线程服务器,并实现 memcached 使用的线程池模型,它使用一个调度程序线程和几个工作线程(但问题不在于 libev 或 memcached)。

我定义了一个类WorkerThreadPool,就像

class WorkerThreadPool 
{
//...
private:
    WorkerThread *worker_threads; //worker threads, enough space allocated
};

并且WorkerThread是下面的struct(省略一些不必要的字段)

typedef struct {
    thread_t tid;
    std::queue<event_entry *> event_queue; //event_entry is irrelavant here
}WorkerThread;

然后在WorkerThreadPool类中有一个private static成员函数eventHandler,我在其中访问了其中一个线程结构(所有线程都已成功创建),如下

WorkerThread *wthread = &worker_threads[0];
if(whtread->event_queue.empty()){
    std::cout << "Empty!\n";
}else{
    std::cout << "Not empty.\n";
    event_entry *evt = wthread->event_queue.front();
    std::cout << "fine.\n";
}

但是,它在“Not empty.\n”输出后立即崩溃,因为它没有打印“fine.\n”。

一开始我以为是因为静态成员函数不能访问非静态成员,但是当我将worker_threads改为静态时,错误仍然存​​在。我还尝试将worker_threads 修改为公开,但没有运气。

现在我真的很困惑,我已经被困了好几天了。谁能帮帮我?

【问题讨论】:

  • 在读写队列之前,你会用互斥锁之类的东西锁定队列吗?
  • 可能不相关,但请小心使用缓冲输出作为调试工具。如果输出缓冲区没有被刷新,那么你的程序可能没有在你认为的地方崩溃。您可以将这些换行符替换为 std::endl,以确保在崩溃前将输出显示在屏幕上。
  • @NeilButterworth 是的,WorkerThread 结构中有一个互斥锁。
  • @NeilButterworth 我在调用 empty() 之前使用了pthread_mutex_lock(&amp;wthread-&gt;event_queue_lock);,互斥锁与错误有什么关系吗?我不是很熟悉。

标签: c++ multithreading stl memcached threadpool


【解决方案1】:
event_entry *evt = wthread->event_queue.front();

队列为空时出现问题。

你需要使用:

WorkerThread *wthread = &worker_threads[0];
if(whtread->event_queue.empty())
{
    std::cout << "Empty!\n";
}
else
{
    std::cout << "Not empty.\n";
    event_entry *evt = wthread->event_queue.front();
}
std::cout << "fine.\n";

【讨论】:

  • 您好,感谢您的回答,但实际上,即使它输出“非空”,它也会崩溃。之前的输出只是为了确保它不为空。我将修改我的问题,使其不那么令人困惑。
猜你喜欢
  • 1970-01-01
  • 2011-10-18
  • 2017-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多