C ++将多个对象传递给线程中的函数
Posted
技术标签:
【中文标题】C ++将多个对象传递给线程中的函数【英文标题】:C++ Passing multiple objects to a function in threads 【发布时间】:2019-11-12 10:45:54 【问题描述】:我在线程化和将同一类的多个对象传递给函数时遇到问题。它是一个外部函数,我想在其中对每个传递的对象调用一个类方法。 我尝试传递一个对象向量以及一个指针向量。我也尝试过通过引用传递它们。
请指定,我有一个“Gas”类,其中 3 个对象是在前面的代码中构造的。我之前在线程中调用了很多方法,所以我猜这个类没有问题。 编译器返回很长的错误,带有 _M_invoke(_Index_tuple<_indices...>):
.In file included from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/thread:39:0,
from ./src/../input.h:22,
from ./src/mass_source.cpp:12:
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/functional: In instantiation of 'struct std::_Bind_simple<void (*(int, std::reference_wrapper<std::vector<Ref::Gas> >))(int, std::vector<Ref::Gas>&)>':
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/thread:142:59: required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(int, std::vector<Ref::Gas>&); _Args = int&, std::reference_wrapper<std::vector<Ref::Gas, std::allocator<Ref::Gas> > >]'
./src/mass_source.cpp:86:50: required from here
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/functional:1505:61: error: no type named 'type' in 'class std::result_of<void (*(int, std::reference_wrapper<std::vector<Ref::Gas> >))(int, std::vector<Ref::Gas>&)>'
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/functional:1526:9: error: no type named 'type' in 'class std::result_of<void (*(int, std::reference_wrapper<std::vector<Ref::Gas> >))(int, std::vector<Ref::Gas>&)>'
_M_invoke(_Index_tuple<_Indices...>)
错误消息来自我的“原始”代码,其中我已注释掉所有行,这些行未在下面显示。据报道令人困惑,这里有一个解释:
from ./src/../input.h:22 - inclusion of thread library
from ./src/mass_source.cpp:12: - inclusion of the above input.h file
./src/mass_source.cpp:86: - calc_ms fucntion call
下面附上类声明:
namespace Ref
class Gas
public:
Gas(const int id, const int& imax, const int& jmax)
id_ = id;
NX_ = imax;
NR_ = jmax;
void set_ms(int m, double& mass_source)
ms_[m] = mass_source;
private:
int id_;
int NX_, NR_;
std::vector<double> ms_;
;
//end of namespace
调用我遇到问题的函数的代码(包括 Gas 对象及其指针的创建):
using namespace Ref;
void calc_ms(int m, std::vector<Gas>& GAS);
int main()
int i;
std::vector<Gas> gases;
std::vector<Gas*> ptr_gas(3);
for(i = 0; i < 3; i++)
gases.push_back(Gas(i, grid));
for(i = 0; i < 3; i++)
ptr_gas[i] = &gases[i];
std::vector<std::thread*> th_gas;
for(i = 0; i < 20; i++)
std::thread *thr = new std::thread(calc_ms, i, std::ref(gases));
th_gas.push_back(thr);
for(auto &X : th_gas)
X->join();
delete X;
th_gas.clear();
还有calc_ms函数定义:
using namespace Ref;
void calc_ms(int m, std::vector<Gas>& GAS)
double MassSourceCH4 = .... ;
double MassSourceCO = .... ;
double MassSourceCO2 = .... ;
GAS[0].set_ms(m, MassSourceCH4);
GAS[1].set_ms(m, MassSourceCO);
GAS[2].set_ms(m, MassSourceCO2);
我也尝试过通过拷贝传递gas,并将ptr_gas作为参考和拷贝。
注释:Gas 类的 ms_ 成员在代码中的其他位置调整了大小,因此使用索引的分配不是问题。
【问题讨论】:
在main函数的文件中。你知道如何帮助我,或者你只是试图证明我什么都不知道? 那么你为什么不展示我们呢?这需要成为minimal reproducible example 的一部分。再一次,哪一行是源文件mass_source.cpp
的第 86 行?一个好的minimal reproducible example 应该是复制您所询问的问题的最小可能程序,并且为了使其完美,我们应该能够复制粘贴它并自己复制问题,而不需要我们编写任何额外的代码。
更好,now with quite some editing I can build it。但不要复制你得到的错误。哪种表示错误的来源不在您显示的代码中。
如果我将std::ref
更改为std::cref
,我设法有点replicate the error。请检查您不使用的实际代码std::cref
。
感谢您的努力。我检查了,不幸的是它是 std::ref ...我会尝试安装其他编译器。也许这就是问题所在......
【参考方案1】:
这是一个简化版本,展示了如何正确使用线程以及如何通过引用将向量传递给线程:
class Gas /*...*/ ;
void calc_ms(int m, std::vector<Gas>& gases);
int main()
std::vector<Gas> gases;
std::vector<std::thread> th_gas;
for(int i = 0; i < 20; ++i)
th_gas.emplace_back(calc_ms, i, std::ref(gases));
for(auto& t : th_gas)
t.join();
th_gas.clear();
【讨论】:
@Padzak 在那种情况下,我怀疑任何事情都会发生。 嗯,问题不在于线程本身,而在于将对象向量传递给被调用函数 @Padzak 这个例子通过引用将向量传递给calc_ms
。你真的应该认真对待,否则你将无济于事。
什么意思?我想通过引用传递它。
@Padzak 我冒着重复自己的风险:这个例子通过引用将向量传递给calc_ms
。以上是关于C ++将多个对象传递给线程中的函数的主要内容,如果未能解决你的问题,请参考以下文章