我写这不得不接受和翻译特定消息格式的客户端 - 服务器守护程序,检查他们提交的所有活动提交给数据库。 计划是多线程的。 于是,我开始工作,并开始在一些情况下得到SIGSEGV。 因此,我不得不重新设计了一个程序,一切重新开始。 我想知道,如果有任何“最佳做法”或如何SIGSEGV的风险降到最低提示? 我知道,每个指针应在使用前删除后进行检查和无效,但如果有任何高层次,设计技巧?
PS对不起,如果我的问题,如果很哑,但我用Google搜索这个话题并没有发现有关此主题的任何合理的文章。 你所有的意见表示赞赏。
并发可很多问题的根源,在几个不同的方式,和SIGSEV是问题之一。 初学者可能会传递一个指针Data* p;
两个线程,并在退出之前让他们执行该代码。
if(p){
delete p->data;
delete p;
p = NULL;
}
你只需要两个线程来见p非空,抢占有SIGSEV场景。 使用标准的容器或者智能指针作为@jogojapan指出,可以缓解这一问题。
段错误的主要来源是
- 未初始化的指针(或一般未初始化的变量)
- 外的约束访问阵列
- 编码糟糕的指针算术
对付这种情况的主要策略包括:
- 总是初始化变量,尤其是三分球
- 避免裸指针(喜欢智能指针,如
std::unique_ptr
或std::shared_ptr
为自己的数据指针,如果你想在仅仅点东西使用迭代器标准集装箱) - 使用标准的容器(例如
std::vector
),而不是阵列和指针算术
正如在评论中提到的,编码不并发或并行化可能会导致分段错误(和其他许多问题),以类似的方式初始化的变量就可以了,因为它们可能导致变量的值被意外地改变。 通用策略来处理这包括:
- 避免共享数据 - 更喜欢线程间通信消息/队列
- 如果您有共享数据,并至少有一个线程写入这些数据,使用互斥,
std::atomic
或类似的保护
然而,既可能在某些情况下,意味着你失去了显著的性能优势。 获取并行算法是正确的仔细分析和设计的问题。