Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何停止std/boost::thread复制对象而不是传递引用?_C++_Multithreading_Boost_C++11_Boost Thread - Fatal编程技术网

C++ 如何停止std/boost::thread复制对象而不是传递引用?

C++ 如何停止std/boost::thread复制对象而不是传递引用?,c++,multithreading,boost,c++11,boost-thread,C++,Multithreading,Boost,C++11,Boost Thread,从这个示例项目的输出中,我看到我的对象创建了三个副本,而我预期只有一个副本。我只想要一个。我该如何解决这个问题 在我的实际代码中,ThreadedThing是一个很大/很重的类,它位于线程池中,我宁愿只拥有我真正需要的数量。但我已经编写了一个演示应用程序(如下),演示了这种行为。我从Boost线程示例中复制基本代码,所以我希望它能正常工作,所以我担心这是一个C++新手问题。 我以前编写过多线程代码,但在Delphi中,而不是C++。对于这段代码,valgrind说没有泄漏,这一切都很好,但仍然有

从这个示例项目的输出中,我看到我的对象创建了三个副本,而我预期只有一个副本。我只想要一个。我该如何解决这个问题

在我的实际代码中,ThreadedThing是一个很大/很重的类,它位于线程池中,我宁愿只拥有我真正需要的数量。但我已经编写了一个演示应用程序(如下),演示了这种行为。我从Boost线程示例中复制基本代码,所以我希望它能正常工作,所以我担心这是一个C++新手问题。

我以前编写过多线程代码,但在Delphi中,而不是C++。对于这段代码,valgrind说没有泄漏,这一切都很好,但仍然有三个创建的对象,我更希望有一个

#include <iostream>
#include <boost/thread.hpp>

using namespace std;

class ThreadedThing {
public:
    ThreadedThing() {
        cout << "ThreadedThing created" << endl;
    }
    ThreadedThing(const ThreadedThing &orig) {
        cout << "ThreadedThing copy created" << endl;
    }
    ~ThreadedThing() {
        cout << "ThreadedThing destroyed" << endl;
    }
    void operator()() {
        cout << "ThreadedThing running" << endl;
        sleep(2);
    }
};

int main() {
    std::vector < shared_ptr < boost::thread >> threads;
    cout << "Started" << endl;

    ThreadedThing thing;
    std::shared_ptr<boost::thread> thread(new boost::thread(thing));
    threads.push_back(thread);

    for (std::vector < std::shared_ptr < boost::thread >> ::iterator it = threads.begin(); it != threads.end(); ++it) {
        (*it)->join();
        cout << "joined" << endl;
    }
    cout << "stopped" << endl;
    return 0;
}

/* output
Started
ThreadedThing created
ThreadedThing copy created
ThreadedThing copy created
ThreadedThing destroyed
ThreadedThing running
ThreadedThing destroyed
joined
stopped
ThreadedThing destroyed
*/
#包括
#包括
使用名称空间std;
类线程化{
公众:
线状物{

cout有很好的文档证明,
boost::thread
的构造函数与
std::thread
一样,不接受引用作为参数。要解决这个问题,您可以编写一个包含引用的小shell对象,并在复制时保留它

我就是这样做的:

/* container to allow passing an object reference to std::thread()
 * without this std::thread() would run on a copy
 */
template<typename T>
struct holder {
    holder(T& payload) : payload(payload) {}
    void operator()() { payload(); }

    T& payload;
};
允许将对象引用传递到std::thread()的容器 *如果没有此std::thread()将在副本上运行 */ 模板 结构持有者{ 保持架(T和有效载荷):有效载荷(有效载荷){} void运算符(){payload();} T&有效载荷; };
然后像这样使用它:

BackgroundTaskQueue queue;

// start worker thread
holder<BackgroundTaskQueue> h(queue);
queuethread = new std::thread(h);
// h is not needed anymore
BackgroundTaskQueue队列;
//启动工作线程
持有人h(排队);
queuethread=新标准::线程(h);
//不再需要h了

在C++11中使用
std::ref
或者在无法访问C++11时使用
boost::ref

太好了,谢谢。这正是我想知道的。如果C++11可用,也可以使用
std::ref
/
std::cref
。现在我使用了更好的搜索词,我找到了很多关于这个问题的答案。std::ref看起来像什么我不想,而不是在我的代码中添加模板。谢谢……是的,如果您可以限制自己与C++11的兼容性,这是正确的。无论如何,不要忘记接受答案。如果不使用C++11,请使用
boost::ref
boost::cref