Wic*_*par 1 c++ concurrency mutex condition-variable
你好,
我是C++的新手,但我有6年的Java经验,2年的C经验和一些并发基础知识.我正在尝试创建一个线程池来处理任务.它位于相关测试主体的下方.
似乎错误是由...生成的
void ThreadPool::ThreadHandler::enqueueTask(void (*task)(void)) {
std::lock_guard<std::mutex> lock(queueMutex);
Run Code Online (Sandbox Code Playgroud)
正如我的调试器所说,但是做传统的cout调试,我发现有时候它可以在没有segfaulting和删除的情况下工作
threads.emplace(handler->getSize(), handler);
Run Code Online (Sandbox Code Playgroud)
从ThreadPool::enqueueTask()大大提高稳定性.
总的来说,我认为这与我对condition_variable(称为idler)的错误使用有关.
编译器:CLION中的minGW-w64
的.cpp
#include <iostream>
#include "ThreadPool.h"
ThreadPool::ThreadHandler::ThreadHandler(ThreadPool *parent) : parent(parent) {
thread = std::thread([&]{
while (this->parent->alive){
if (getSize()){
std::lock_guard<std::mutex> lock(queueMutex);
(*(queue.front()))();
queue.pop_front();
} else {
std::unique_lock<std::mutex> lock(idlerMutex);
idler.wait(lock);
}
}
});
}
void ThreadPool::ThreadHandler::enqueueTask(void (*task)(void)) {
std::lock_guard<std::mutex> lock(queueMutex);
queue.push_back(task);
idler.notify_all();
}
size_t ThreadPool::ThreadHandler::getSize() {
std::lock_guard<std::mutex> lock(queueMutex);
return queue.size();
}
void ThreadPool::enqueueTask(void (*task)(void)) {
std::lock_guard<std::mutex> lock(threadsMutex);
std::map<int, ThreadHandler*>::iterator iter = threads.begin();
threads.erase(iter);
ThreadHandler *handler = iter->second;
handler->enqueueTask(task);
threads.emplace(handler->getSize(), handler);
}
ThreadPool::ThreadPool(size_t size) {
for (size_t i = 0; i < size; ++i) {
std::lock_guard<std::mutex> lock(threadsMutex);
ThreadHandler *handler = new ThreadHandler(this);
threads.emplace(handler->getSize(), handler);
}
}
ThreadPool::~ThreadPool() {
std::lock_guard<std::mutex> lock(threadsMutex);
auto it = threads.begin(), end = threads.end();
for (; it != end; ++it) {
delete it->second;
}
}
Run Code Online (Sandbox Code Playgroud)
.H
#ifndef WLIB_THREADPOOL_H
#define WLIB_THREADPOOL_H
#include <mutex>
#include <thread>
#include <list>
#include <map>
#include <condition_variable>
class ThreadPool {
private:
class ThreadHandler {
std::condition_variable idler;
std::mutex idlerMutex;
std::mutex queueMutex;
std::thread thread;
std::list<void (*)(void)> queue;
ThreadPool *parent;
public:
ThreadHandler(ThreadPool *parent);
void enqueueTask(void (*task)(void));
size_t getSize();
};
std::multimap<int, ThreadHandler*> threads;
std::mutex threadsMutex;
public:
bool alive = true;
ThreadPool(size_t size);
~ThreadPool();
virtual void enqueueTask(void (*task)(void));
};
#endif //WLIB_THREADPOOL_H
Run Code Online (Sandbox Code Playgroud)
主要:
#include <iostream>
#include <ThreadPool.h>
ThreadPool pool(3);
void fn() {
std::cout << std::this_thread::get_id() << '\n';
pool.enqueueTask(fn);
};
int main() {
std::cout << "Hello, World!" << std::endl;
pool.enqueueTask(fn);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
你的main()函数调用enqueueTask().
紧接着,你的main()回报.
这样可以使齿轮运转,从而减少您的过程.这涉及调用所有全局对象的析构函数.
ThreadPool然后,析构函数继续删除所有动态范围的线程.
虽然线程仍在运行.随之而来的是欢闹.
您需要实现有序关闭所有线程的过程.
这意味着设置active为false,踢出小腿中的所有线程,然后加入所有线程,然后让大自然走上正轨,最后摧毁一切.
PS - 您需要修复如何alive检查.您还需要访问alive线程安全,受互斥锁保护.问题是线程可能会锁定两个不同的互斥锁之一.这使得这个过程有点复杂.这里有一些重新设计是有序的.
| 归档时间: |
|
| 查看次数: |
1434 次 |
| 最近记录: |