简体   繁体   English

传递给线程后保持引用有效

[英]Keeping reference alive after being passed to thread

I have a graph object that I am passing into a thread like this: 我有一个图对象,我正在将其传递给这样的线程:

void MyClass::execute_subqueries(Graph& g, vector<query>&& queries) {
  for (size_t i = 0; i < queries.size(); i++) {
    threads.emplace_back(thread(my_thread, ref(g), queries[i]));
  }
}

I want to make a copy of the Graph object g because I will make changes to it as my thread is running. 我想复制Graph对象g,因为我将在线程运行时对其进行更改。 I only want to make one copy and pass a reference to all the threads I'm starting in the for loop. 我只想制作一个副本并将引用传递给我在for循环中启动的所有线程。 I don't want to make a copy for each thread because the Graph is large and it's expensive to clone it. 我不想为每个线程制作一个副本,因为Graph很大,克隆它很昂贵。

The problem is that I can't figure out how to keep my Graph object alive. 问题是我无法弄清楚如何使我的Graph对象保持活动状态。 I think after I pass in the reference, the Graph object gets deallocated and my threads do not produce the result I expect. 我认为在传递引用后,将释放Graph对象,并且我的线程不会产生我期望的结果。 What is a good way to do this? 什么是这样做的好方法?

Your flags tell me that you use c++11, so why don't you use a 您的标志告诉我您使用的是c ++ 11,那么为什么不使用a

std::vector< std::shared_ptr<Graph> > graphs;

and pass the shared pointers to the threads? 并将共享的指针传递给线程? They will keep your graphs alive as long as they are used and take care of the cleanup afterwards... 只要使用它们,它们就会使您的图形保持活动状态,并在之后进行清理。

Since you want to make a copy of the graph, you might as well place it in an std::shared_ptr , and pass it to each of the threads (note that you'll be passing copies of the same pointer, so there won't be a copy per thread). 由于您想复制图表,因此您最好将其放置在std::shared_ptr ,并将其传递给每个线程(请注意,您将传递相同指针的副本,因此不会) t是每个线程的副本)。

Consider something like this: 考虑这样的事情:

// A vector of pointers to Graph
vector<shared_ptr<Graph>> graphs;

...

// Make a shared allocated copy.
graphs.emplace_back(std::make_shared<Graph>(g));

(Note that this requires c++11 settings.) (请注意,这需要c ++ 11设置。)

It can be done using shared_ptr as suggested in the other answers but it really depends on what your program is doing. 可以按照其他答案中的建议使用shared_ptr完成此操作,但这实际上取决于您的程序在做什么。 Before the for loop can try: 在for循环可以尝试之前:

std::shared<Graph> gPtr(new Graph(g));
//std::shared<Graph> gPtr(g.clone()); // guess, you mentioned cloning

Then start the threads. 然后启动线程。 Naming can be better. 命名可以更好。 I presume my_thread is not really a thread instance but a function (else it won't compile). 我认为my_thread并不是一个线程实例,而是一个函数(否则它将无法编译)。 Make it take a shared_ptr instead of reference, etc. 使它采用shared_ptr而不是引用等。

You probably meant - if threads is std::vector (guess): 您可能的意思是-如果线程是std :: vector(猜测):

threads.push_back(std::thread(my_thread_fct, gPtr, queries[i]));

or 要么

threads.emplace_back(my_thread_fct, gPtr, queries[i]);

@JoachimPileborg is right - need more context/code to understand what is going on. @JoachimPileborg是正确的-需要更多上下文/代码来了解发生了什么。 What is the output of all this? 这一切的输出是什么? Would you extract something from that processed cloned Graph or else? 您会从处理后的克隆图中提取某些内容吗? Depending on those design decisions the code would look pretty different... 根据这些设计决策,代码看起来会完全不同...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM