Al *_*epé 6 c++ multithreading mutex c++11
我正在尝试使用互斥锁来防止多个线程同时读取变量。
\n\n我的代码生成多个“Carriers”对象,所有对象都具有相同的“SMSDetector”,并且在尝试评估某些 Dolfin 函数时代码崩溃(分段错误)(是的,我使用 Fenics 库进行一些 FEM 计算);所以我试图在评估之前锁定互斥体并在评估之后解锁。
\n\n我现在的问题是,我需要复制/移动构造函数以使 Carrier 类能够 mov/copi,但我似乎没有正确理解它们。没有互斥体我得到:Carrier.cpp:203:42: error: \xe2\x80\x98Carrier& operator=(const Carrier&)\xe2\x80\x99 must be a nonstatic member function Carrier& operator = (const Carrier& other)
通过互斥体我得到:Carrier.cpp:200:49: error: no matching function for call to \xe2\x80\x98std::lock_guard<std::mutex>::lock_guard(const std::mutex&)\xe2\x80\x99\n std::lock_guard<std::mutex> lock(other.safeRead);
我正在尝试用 c++11 标准编写整个程序,因此如果有人有 c++11 解决方案,我将非常感激。
\n\n这是冲突的代码:\n
\n\nstd::valarray<double> Carrier::simulate_drift(double dt, double max_time, double x_init, double y_init )\n\n{\n _x[0] = x_init;\n _x[1] = y_init;\n\n // get number of steps from time\n int max_steps = (int) std::floor(max_time / dt);\n\n std::valarray<double> i_n(max_steps); // valarray to save intensity\n\n runge_kutta4<std::array< double,2>> stepper;\n\n // wrapper for the arrays using dolphin array class\n Array<double> wrap_x(2, _x.data());\n Array<double> wrap_e_field(2, _e_field.data());\n Array<double> wrap_w_field(2, _w_field.data());\n\n double t=0.0; // Start at time = 0\n\n for ( int i = 0 ; i < max_steps; i++)\n {\n\n if (t < _gen_time) // If CC not yet generated\n { \n i_n[i] = 0;\n } \n else if (_detector->is_out(_x)) // If CC outside detector\n { \n i_n[i] = 0;\n break; // Finish (CC gone out)\n } \n else\n { \n safeRead.lock();\n _detector->get_d_f_grad()->eval(wrap_e_field, wrap_x);\n _detector->get_w_f_grad()->eval(wrap_w_field, wrap_x);\n safeRead.unlock();\n _e_field_mod = sqrt(_e_field[0]*_e_field[0] + _e_field[1]*_e_field[1]);\n i_n[i] = _q *_sign* _mu.obtain_mobility(_e_field_mod) * (_e_field[0]*_w_field[0] + _e_field[1]*_w_field[1]);\n stepper.do_step(_drift, _x, t, dt);\n // Trapping effects due to radiation-induced defects (traps) implemented in CarrierColleciton.cpp\n } \n t+=dt;\n }\n return i_n;\n}\n/*\n * Copy initialization\n */\nCarrier::Carrier(const Carrier& other)\n{\n _carrier_type = other._carrier_type;\n _q = other._q;\n _gen_time = other._gen_time;\n _x = other._x; \n _e_field = other._e_field; \n _w_field = other._w_field;\n _e_field_mod = other._e_field_mod;\n _sign = other._sign; \n _detector = other._detector;\n _myTemp = other._myTemp;\n _drift = other._drift;\n _mu = other._mu;\n _trapping_time = other._trapping_time;\n std::lock_guard<std::mutex> lock(other.safeRead);\n}\n\n/*\n * Copy assignment\n */\nCarrier& operator = (const Carrier& other) \n{\n// std::lock(safeRead, other.safeRead;\n// std::lock_guard<std::mutex> self_lock(safeRead, std::adopt_lock;\n// std::lock_guard<std::mutex> other_lock(other.safeRead, std::adopt_lock;\n std::lock_guard<std::mutex> self_lock(safeRead, std::adopt_lock);\n std::lock_guard<std::mutex> other_lock(other.safeRead, std::adopt_lock);\n _carrier_type = other._carrier_type;\n _q = other._q;\n _gen_time = other._gen_time;\n _x = other._x; \n _e_field = other._e_field; \n _w_field = other._w_field;\n _e_field_mod = other._e_field_mod;\n _sign = other._sign; \n _detector = other._detector;\n _myTemp = other._myTemp;\n _drift = other._drift;\n _trapping_time = other._trapping_time;\n return *this;\n}\n\n\n/*\n * Move initialization\n */\nCarrier::Carrier(Carrier&& other)\n{\n _carrier_type = std::move(other._carrier_type);\n _q = std::move(other._q);\n _gen_time = std::move(other._gen_time);\n _x = std::move(other._x); \n _e_field = std::move(other._e_field); \n _w_field = std::move(other._w_field);\n _e_field_mod = std::move(other._e_field_mod);\n _sign = std::move(other._sign); \n _detector = std::move(other._detector);\n _myTemp = std::move(other._myTemp);\n _drift = std::move(other._drift);\n _mu = std::move(other._mu);\n _trapping_time = std::move(other._trapping_time);\n std::lock_guard<std::mutex> lock(other.safeRead);\n}\n\n/*\n * Move assignment\n */\nCarrier& operator = ( Carrier&& other) \n{\n std::lock(safeRead, other.safeRead);\n std::lock_guard<std::mutex> self_lock(safeRead, std::adopt_lock);\n std::lock_guard<std::mutex> other_lock(other.safeRead, std::adopt_lock);\n _carrier_type = std::move(other._carrier_type);\n other._carrier_type = NULL;\n _q = std::move(other._q);\n other._q = 0;\n _gen_time = std::move(other._gen_time);\n other._gen_time = 0;\n _x = std::move(other._x); \n other._x = {0,0};\n _e_field = std::move(other._e_field); \n other._e_field = {0,0};\n _w_field = std::move(other._w_field);\n other._w_field = {0,0};\n _e_field_mod = std::move(other._e_field_mod);\n other._e_field_mod = 0;\n _sign = std::move(other._sign); \n other._sign = 0;\n _detector = std::move(other._detector);\n other._detector = NULL;\n _myTemp = std::move(other._myTemp);\n other._myTemp = 0;\n _drift = std::move(other._drift);\n _mu = std::move(other._mu);\n _trapping_time = std::move(other._trapping_time);\n other._trapping_time = 1e300;\n return *this;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n如果有帮助,我会上传更多代码,但我觉得这已经足够了。
\n\n先谢谢您的帮助
\n\n编辑:类声明(完整头文件):
\n\n#ifndef CARRIER_H\n#define CARRIER_H\n\n#include <valarray>\n#include <mutex>\n\n#include <CarrierTransport.h>\n#include <SMSDetector.h>\n\n#ifndef Q_MOC_RUN // See: https://bugreports.qt-project.org/browse/QTBUG-22829\n#include <boost/numeric/odeint/stepper/runge_kutta4.hpp>\n#endif\n\nusing namespace boost::numeric::odeint;\n\nclass Carrier\n{\n private:\n char _carrier_type;\n double _q; // charge\n double _gen_time; // instant of generation of the carrier\n std::array< double,2> _x; // carrier position array\n std::array< double,2> _e_field; // electric field at the carrier position\n std::array< double,2> _w_field; // weighting field at the carrier positions\n double _e_field_mod;\n int _sign; // sign to describe if carrier moves in e field direction or opposite\n// std::mutex safeRead;\n\n SMSDetector * _detector;\n double _myTemp; // Temperature of the detector\n DriftTransport _drift;\n JacoboniMobility _mu;\n double _trapping_time;\n\n public:\n Carrier( char carrier_type, double q, double x_init, double y_init, SMSDetector * detector, double gen_time);\n Carrier(Carrier&& other); // Move declaration\n Carrier& operator = (Carrier&& other); // Move assignment\n Carrier(const Carrier& other); // Copy declaration\n Carrier& operator = (const Carrier& other); // Copy Assignment\n ~Carrier();\n\n char get_carrier_type();\n\n std::array< double,2> get_x();\n double get_q();\n\n std::valarray<double> simulate_drift( double dt, double max_time);\n std::valarray<double> simulate_drift(double dt, double max_time, double x_init, double y_init );\n};\n\n#endif // CARRIER_H\nRun Code Online (Sandbox Code Playgroud)\n
在您的实现中operator=,您需要指定类名:
Carrier& Carrier::operator = (const Carrier& other)。
锁定互斥体时,您会收到您所描述的编译错误,因为std::mutex::lock()它不是一种const方法。在赋值运算符中,您应该other按引用获取参数。const因此,它试图const在const对象上调用非函数,从而导致编译错误。
mutable解决方法是按照类声明中的方式声明成员Carrier:
mutable std::mutex safeRead;
这允许您解决编译错误。
| 归档时间: |
|
| 查看次数: |
2664 次 |
| 最近记录: |