访问类成员而不复制此变量或互斥变量
Access class members without copying this or mutex variable
我正在尝试创建一个简单的Worker类,它将创建多个线程和一组任务供线程运行。这很有教育意义,但我已经尝试过询问同学并寻找不同的答案,我认为我缺少一些"简单"/基本的东西。
关于互斥变量的设置位置,我遇到了一些问题。我相信我希望每个Worker对象都有一个,因为每个对象创建的线程完全不相关。现在,我正试图将this
传递给lambda方法,该方法会添加到线程集,但这会复制互斥体,互斥体会删除它。有没有办法独立复制我需要的每个类成员,或者我应该创建一个复制构造函数?我只是想把我需要的类变量传递给lambda。这是我的代码:
// TDAT2004Task2.cpp : Defines the entry point for the application.
//
#include <functional>
#include <iostream>
#include <list>
#include <vector>
#include <mutex>
#include <thread>
using namespace std;
class Worker {
int threads;
mutable mutex tasks_mutex;
vector<thread> worker_threads;
list<function<void()>> tasks;
public:
Worker(int threadAmount) {
threads = threadAmount;
}
void start() {
for (int i = 0; i < threads; i++) {
//This is the place errors occur. I'm copying the this element, and thus deleting my
//mutex variable.
worker_threads.emplace_back([this] {
while (true) {
function<void()> task;
{
lock_guard<mutex> lock(tasks_mutex);
if (!tasks.empty()) {
task = *tasks.begin();
tasks.pop_front();
}
}
if (task) {
task();
}
}
});
}
for (auto& thread : worker_threads) {
thread.join();
}
}
void post(function<void()> function) {
lock_guard<mutex> lock(tasks_mutex);
tasks.emplace_back(function);
}
};
int main()
{
//This does not compile.
Worker worker_threads = Worker(4);
}
我在VS:中的错误消息
>------ Build All started: Project: TDAT2004Task2, Configuration: x64-Debug ------
[1/2] C:PROGRA~2MICROS~22019COMMUN~1VCToolsMSVC1424~1.283binHostX64x64cl.exe /nologo /TP /DWIN32 /D_WINDOWS /W3 /GR /EHsc /MDd /Zi /Ob0 /Od /RTC1 /showIncludes /FoTDAT2004Task2CMakeFilesTDAT2004Task2.dirTDAT2004Task2.cpp.obj /FdTDAT2004Task2CMakeFilesTDAT2004Task2.dir /FS -c ......TDAT2004Task2TDAT2004Task2.cpp
FAILED: TDAT2004Task2/CMakeFiles/TDAT2004Task2.dir/TDAT2004Task2.cpp.obj
C:PROGRA~2MICROS~22019COMMUN~1VCToolsMSVC1424~1.283binHostX64x64cl.exe /nologo /TP /DWIN32 /D_WINDOWS /W3 /GR /EHsc /MDd /Zi /Ob0 /Od /RTC1 /showIncludes /FoTDAT2004Task2CMakeFilesTDAT2004Task2.dirTDAT2004Task2.cpp.obj /FdTDAT2004Task2CMakeFilesTDAT2004Task2.dir /FS -c ......TDAT2004Task2TDAT2004Task2.cpp
C:UsersEvensourcereposTDAT2004Task2TDAT2004Task2TDAT2004Task2.cpp(74): error C2280: 'Worker::Worker(const Worker &)': attempting to reference a deleted function
......TDAT2004Task2TDAT2004Task2.cpp(69): note: compiler has generated 'Worker::Worker' here
......TDAT2004Task2TDAT2004Task2.cpp(69): note: 'Worker::Worker(const Worker &)': function was implicitly deleted because a data member invokes a deleted or inaccessible function 'std::mutex::mutex(const std::mutex &)'
C:Program Files (x86)Microsoft Visual Studio2019CommunityVCToolsMSVC14.24.28314includemutex(92): note: 'std::mutex::mutex(const std::mutex &)': function was explicitly deleted
ninja: build stopped: subcommand failed.
控制台中来自cpp的错误消息:
C:UsersEvensourcereposTDAT2004Task2TDAT2004Task2>gcc TDAT2004Task2.cpp
TDAT2004Task2.cpp: In function 'int main()':
TDAT2004Task2.cpp:74:34: error: use of deleted function 'Worker::Worker(Worker&&)'
Worker worker_threads = Worker(4);
^
TDAT2004Task2.cpp:18:7: note: 'Worker::Worker(Worker&&)' is implicitly deleted because the default definition would be ill-formed:
class Worker {
^~~~~~
TDAT2004Task2.cpp:18:7: error: use of deleted function 'std::mutex::mutex(const std::mutex&)'
In file included from /usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/mutex:43:0,
from TDAT2004Task2.cpp:13:
/usr/lib/gcc/x86_64-pc-cygwin/7.4.0/include/c++/bits/std_mutex.h:97:5: note: declared here
mutex(const mutex&) = delete;
^~~~~
感谢您的回复!请指出我犯过的任何愚蠢的错误,我只是想学习最好的做法。
问题是,您定义了一个复制构造函数。因此,您没有默认的移动构造函数。
我看不出如何拥有正确的复制构造函数,因为std::thread
不能复制,因此std::vector<std::thread>
不能复制。
默认的move构造函数应该适用于您的案例。
所以要明确地添加行:
public:
Worker(const Worker&) = delete;
Worker& operator=(const Worker&) = delete;
Worker(Worker&&) = default;
Worker& operator=(Worker&&) = default;
你的工人阶级。
相关文章:
- 是否可以初始化不可复制类型的成员变量(或基类)
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 访问类成员而不复制此变量或互斥变量
- 字符串变量,比如说"字符串str",可以直接复制到数组中吗?
- 复制文件流C++静态变量
- 为什么我可以使用 memcpy 将一个对象变量复制到另一个对象变量
- 使变量不可复制的紧凑方法
- C++为具有引用成员变量的类创建复制构造函数
- 如何将几个变量复制到其他变量
- 如何在 cuda 中将结构的指针变量从主机复制到设备
- memcpy() 在一个类中被调用以复制到另一个类变量中后会引发异常
- 复制一个对象并使两者共享一个成员变量 (C++)
- 我的 c 字符串复制函数正在损坏其他变量的堆栈
- 如何在不定义目标变量大小的情况下逐个字符将字符串变量复制到另一个字符
- 我的字符串没有从私有变量复制
- 如何在传递右值引用函数参数时从基元类型变量复制
- 将 Timeval 成员变量复制到整数变量
- 从常量变量复制向量
- 将成员变量复制到字节向量中
- 我如何将CHAR变量复制到c++中的WCHAR变量