为向量成员使用线程时出现未知的段错误

时间:2017-02-04 22:16:09

标签: c++ multithreading loops reference segmentation-fault

我正在使用线程从向量中找到每个组件(图形)中最便宜的Edge。它是boruvka算法的实现。

代码在这里:

void findPath(const Graph &component, Edge &edge) {
    if (component.edges.size()<1 || !component.edges.front().weight)return;
    int min = component.edges.front().weight;
    edge = component.edges.front();
    for (Edge e: component.edges) {
        if (e.weight < min) {
            min = e.weight;
            edge = e;
        }
    }
}

Graph boruvkaParalel(Graph *graph) {
Graph mst;
std::vector<Graph> components;
for (int i = 0; i < graph->nodes.size(); ++i) {
    Graph a;
    addEdges(&a, getEdgesForNode(graph->nodes[i], graph));
    a.nodes.push_back(graph->nodes[i]);
    components.push_back(a);
}

while (components.size() > 1) {
Graph toCollapse;
std::vector<std::thread> threads;
std::vector<Edge> minEdges;

for (auto &g: components) {
    minEdges.push_back({});
}

std::atomic_thread_fence(std::memory_order_seq_cst);

for (size_t i=0; i<components.size(); ++i) {
    threads.emplace_back([&]{findPath(components[i], minEdges[i]);});
}

for (auto &i : threads) {
    i.join();
}
for (Edge edge:minEdges) {
    if (!contains(mst, edge) && edge.weight != 0) {
        addEdge(&mst, edge.n1, edge.n2, edge.weight);
        addEdge(&toCollapse, edge.n1, edge.n2, edge.weight);
    }
}
...
//collapse components based on choosen edges
...
}
}

一开始我有组件,其中每个组件都是图形的一个顶点及其所有边缘。然后我为每个组件创建线程,我在其中寻找最便宜的边缘。然后我将minEdges中的所有边合并到mst(最终图形)中,然后根据找到的边缘折叠组件。相同的cykle与更大的组件,直到剩下一个组件。

问题是,有时引用findPath中的组件指向内存中的某个位置,而不是正确的组件。

当我尝试调试它时,一切都很好,它指向正确的组件并完全按照我的意愿保存minEdges。但有时候,即使是在创建线程的循环中,我指的是正确的对象,在findPath中它指向其他地方,然后应该这就是段错误。

我想注意的是,每个线程都在使用它自己的vector成员,而且组件只是用于读取,因此它应该在那里进行更改。在进入线程之前,所有组件都是正确的,顺序解决方案也能正常工作。

是的,有人可以帮帮我吗?如果您想了解更多信息,我会添加它。

0 个答案:

没有答案