马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
我在尝试做一个生产者+消费者多线程模型的时候,在进行调试时,出现报错:
0xC0000005: 读取位置 0x0000000000000070 时发生访问冲突。
以下是我的源代码(生产者部分被略去):export module core.thread;
import std;
import core.constants;
using function = std::function<void()>;
using lock = std::lock_guard<std::mutex>;
export namespace thread
{
class Group
{
protected:
std::queue<function> queue;
public:
std::condition_variable variable;
std::mutex mutex;
Group() = default;
Group(const Group&) = delete;
Group(Group&&) = delete;
std::optional<function> get_task() noexcept
{
lock lock(this->mutex);
if (this->queue.empty())
{
return std::nullopt;
};
function task = this->queue.front();
this->queue.pop();
return task;
};
void add_task(function task) noexcept
{
lock lock(this->mutex);
this->queue.push(task);
this->variable.notify_one();
};
};
class BasicThread
{
protected:
std::thread thread;
choice::status status;
std::string name;
public:
BasicThread() = delete;
BasicThread(const BasicThread&) = delete;
BasicThread(BasicThread&&) = default;
BasicThread(const std::string& name) :
name(name)
{
this->thread = std::thread(&BasicThread::run, this);
};
virtual void run() {};
inline void join() noexcept
{
if (this->thread.joinable())
{
this->thread.join();
};
};
};
class Worker : public BasicThread
{
protected:
std::shared_ptr<Group> group;
public:
Worker() = delete;
Worker(const Worker&) = delete;
Worker(Worker&&) = default;
Worker(const std::string& name, const std::shared_ptr<Group>& group) :
BasicThread(name),
group(group) {};
void run()
{
std::optional<function> current_task;
while (this->status != choice::status::terminating)
{
std::unique_lock<std::mutex> lock{ this->group->mutex };
this->group->variable.wait(lock, [¤t_task, this]() {return current_task = this->group->get_task(); }); // Only runs if a new task is available
lock.unlock();
current_task.value()();
};
};
inline void attach(const std::shared_ptr<Group>& group) noexcept
{
this->group = group;
};
};
};
这是我的调试部分:import core.thread;
import std;
int main()
{
std::shared_ptr<thread::Group> group;
thread::Worker worker{ "test", group };
return 0;
};
你好!你的代码中存在一些问题导致了访问冲突的报错。首先,你在主函数中定义了一个名为`group`的`std::shared_ptr`智能指针,但没有初始化它,所以会导致未定义的行为。你需要为`group`分配内存并初始化它,可以使用`std::make_shared`函数来实现:
std::shared_ptr<thread::Group> group = std::make_shared<thread::Group>();
其次,在`Worker`类的构造函数中,你将`std::shared_ptr`对象传递给了`group`成员,但是在声明`group`时,没有指定它指向的具体类型,这也是引起编译错误的原因。你需要明确指出`group`指向的是`thread::Group`类型:
std::shared_ptr<thread::Group> group;
但是请注意,这只是修复了编译错误,而不是解决访问冲突的问题。要解决访问冲突,你还需要对多线程间的共享资源进行正确的加锁处理。在你的代码中,生产者通过添加任务到队列中来共享资源,消费者通过从队列中获取任务来共享资源。
你可以在生产者添加任务时加锁,以及在消费者获取任务时加锁:
// 生产者
void add_task(function task) noexcept
{
lock lock(this->mutex);
this->queue.push(task);
this->variable.notify_one();
};
// 消费者
void run()
{
std::optional<function> current_task;
while (this->status != choice::status::terminating)
{
std::unique_lock<std::mutex> lock(this->group->mutex);
this->group->variable.wait(lock, [this]() { return !this->group->queue.empty(); }); // 只有当队列非空时才继续执行
current_task = this->group->get_task();
lock.unlock();
if (current_task.has_value())
{
current_task.value()();
}
}
}
这样做的目的是保证在生产者和消费者之间正确地同步资源访问。通过加锁,确保只有一个线程能够同时对资源进行访问,避免访问冲突的问题。
希望以上解答能够帮助到你!如果还有其他问题,请随时提问。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
|