我有一个很大但可能变化的对象,它们被同时写入.我想用互斥锁保护访问权限.为此,我认为我使用了一个std::vector<std::mutex>,但这不起作用,因为std::mutex没有复制或移动构造函数,同时std::vector::resize()需要.
这个难题的推荐解决方案是什么?
编辑:所有C++随机访问容器是否需要复制或移动构造函数来重新调整大小?std :: deque会帮助吗?
再次编辑
首先,感谢您的所有想法.我对避免突变和/或将它们移动到对象中的解决方案不感兴趣(我不提供细节/原因).因此,考虑到我想要一个可调数量的mutices(在没有锁定互斥锁时保证调整的情况)的问题,那么似乎有几种解决方案.
1我可以使用固定数量的mutices并使用哈希函数从对象映射到mutices(如Oblivous上尉的答案).这将导致冲突,但如果mutices的数量远大于线程数,但仍然小于对象数,则冲突的数量应该很小.
2我可以定义一个包装类(如在ComicSansMS的答案中),例如
struct mutex_wrapper : std::mutex
{
mutex_wrapper() = default;
mutex_wrapper(mutex_wrapper const&) noexcept : std::mutex() {}
bool operator==(mutex_wrapper const&other) noexcept { return this==&other; }
};
Run Code Online (Sandbox Code Playgroud)
并使用一个std::vector<mutex_wrapper>.
3我可以std::unique_ptr<std::mutex>用来管理单个互斥体(如Matthias的答案).这种方法的问题是每个互斥锁在堆上单独分配和解除分配.因此,我更喜欢
4 std::unique_ptr<std::mutex[]> mutices( new std::mutex[n_mutex] );
当n_mutex最初分配一定数量的mutices时.如果以后发现这个数字不够,我只是
if(need_mutex > n_mutex) {
mutices.reset( new std::mutex[need_mutex] );
n_mutex = need_mutex;
}
Run Code Online (Sandbox Code Playgroud)
那么我应该使用这些(1,2,4)中的哪一个?
我有一个以std :: mutex为成员的类.我正在尝试创建这样的类的数组
class C
{
int x;
std::mutex m;
};
int main()
{
C c[10];
//later trying to create a temp C
C temp = c[0];
}
Run Code Online (Sandbox Code Playgroud)
显然,由于互斥对象不可复制,因此无法实现上述目标.解决它的方法是通过复制构造函数.
但是,我在创建复制构造函数时遇到问题.我试过了
C (const C &c)
{
x = c.x;
//1. m
//2. m()
//3. m = c.m
}
Run Code Online (Sandbox Code Playgroud)
我不确定3种选择中的正确语法是什么.请帮忙.
假设我正在编写Derived并且必须继承Base,我无法控制并且有两个单独的构造函数和一个已删除的副本和移动构造函数:
struct Base {
Base(int i);
Base(const char *sz);
Base(const Base&) = delete;
Base(const Base&&) = delete;
};
struct Derived {
Derived(bool init_with_string);
};
Run Code Online (Sandbox Code Playgroud)
现在,根据another_param我必须使用构造函数或其他函数初始化我的基类的值; 如果C++不那么严格,那就像是:
Derived::Derived(bool init_with_string) {
if(init_with_string) {
Base::Base("forty-two");
} else {
Base::Base(42);
}
}
Run Code Online (Sandbox Code Playgroud)
(这对于计算值以直接表达式传递给基类构造函数/字段初始化器很麻烦的所有情况也很有用,但我很讨厌)
不幸的是,即使我没有看到特定的codegen或对象模型障碍这种事情,这不是有效的C++,我想不出简单的解决方法.
有什么方法我不知道吗?
我正在尝试使用互斥锁来防止多个线程同时读取变量。
\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 = …Run Code Online (Sandbox Code Playgroud) 虽然我在使用C++ 14规范做自己熟悉,但我已经读过,如果一个类没有显式声明Copy Constructor,Copy Assignment Operator,Move Constructor和Move Assignment Operator,那么编译器应该生成默认实现.
考虑这个空类用于线程安全文件:
class ThreadSafeFile
{
std::mutex m_mutex;
std::string m_FileName;
std::ofstream m_File;
};
Run Code Online (Sandbox Code Playgroud)
当我尝试移动分配它像这样:
ThreadSafeFile file;
ThreadSafeFile file2 = std::move(file);
Run Code Online (Sandbox Code Playgroud)
我收到此编译错误:
函数"ThreadSafeFile :: ThreadSafeFile(const ThreadSafeFile&)"(隐式声明)无法引用 - 它是一个已删除的函数
为什么会这样?
下面是用于重现该错误的最少代码。
#include <iostream>
#include <mutex>
#include <vector>
class A {
std::mutex mutex;
public:
A(){};
};
int main()
{
std::vector<std::pair<std::string,A>> aa;
A a;
//aa.push_back(std::make_pair(std::string("aa"),A()));
//aa.push_back(std::make_pair(std::string("aa"),a));
aa.push_back(std::make_pair(std::string("aa"),std::move(a)));
}
Run Code Online (Sandbox Code Playgroud)
以下是错误。
用于x64的Microsoft(R)C / C ++优化编译器版本19.16.27026.1版权所有(C)Microsoft Corporation。版权所有。
> C:\Program Files (x86)\Microsoft Visual
> Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include\xlocale(319):
> warning C4530: C++ exception handler used, but unwind semantics are
> not enabled. Specify /EHsc C:\Program Files (x86)\Microsoft Visual
> Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include\utility(405):
> error C2440: '<function-style-cast>': cannot convert from 'initializer
> list' to '_Mypair' C:\Program Files (x86)\Microsoft Visual
> Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include\utility(405):
> …Run Code Online (Sandbox Code Playgroud)