如何解决如何创建有限数量的线程?
我是线程初学者,我有一个问题。
我在当前目录中有一个带有所有.txt文件的向量。如何计算给定线程数(默认情况下为4个线程)。
我听说过ThreadPool并找到了以下代码:
ThreadPool.h
#ifndef THREAD_POOL_H
#define THREAD_POOL_H
#include <vector>
#include <queue>
#include <memory>
#include <functional>
#include <stdexcept>
#include <vector>
#include <queue>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
#include <future> // boost future is not working for me
class ThreadPool
{
public:
using Task = std::function<void()>;
explicit ThreadPool(std::size_t threads_count);
~ThreadPool();
template <class T>
auto enqueue(T task) -> std::future<decltype(task())>
{
auto wrapper = std::make_shared<std::packaged_task<decltype(task()) ()>>(std::move(task));
{
boost::unique_lock<boost::mutex> lock(mutex_p);
tasks_p.emplace([=] {
(*wrapper)();
});
}
cond_p.notify_one();
return wrapper->get_future();
}
private:
std::vector<boost::thread> threads_p;
boost::condition_variable cond_p;
boost::mutex mutex_p;
std::queue<Task> tasks_p;
bool isStop = false;
void start(std::size_t threads_count);
void stop() noexcept;
};
ThreadPool.cpp
#include "ThreadPool.h"
void ThreadPool::start(std::size_t threads_count)
{
for (auto i = 0; i < threads_count; ++i)
{
threads_p.emplace_back([=] {
while (true)
{
Task task;
{
boost::unique_lock<boost::mutex>lock(mutex_p);
cond_p.wait(lock,[=] { return isStop || !tasks_p.empty(); });
if (isStop && tasks_p.empty())
break;
task = std::move(tasks_p.front()); // First task of the queue to execute
tasks_p.pop(); // Delete this task
}
task();
}
});
}
}
void ThreadPool::stop() noexcept
{
{
boost::unique_lock<boost::mutex> lock(mutex_p);
isStop = true;
}
cond_p.notify_all();
for (auto& thread : threads_p)
{
thread.join();
}
}
ThreadPool::ThreadPool(std::size_t threads_count)
{
start(threads_count);
}
ThreadPool::~ThreadPool()
{
stop();
}
这是我的柜台课。我用.txt文件的所有名称填充矢量。
Counter.cpp
#include "Counter.h"
Counter::Counter()
{
std::cout << "Error" << "\n";
}
Counter::Counter(std::string& dirname_)
{
dir = dirname_;
// Does exist this folder?
if (bfs::exists(dir) && bfs::is_directory(dir))
{
std::cout << "Dir is exist!\n";
}
else
{
std::cout << "Error: Dir is not exist\n";
}
}
void Counter::allTxtFiles()
{
for (auto& p : bfs::directory_iterator(dir))
{
if (p.path().extension() == ".txt")
txt_files.push_back(p.path().string());
}
}
// Count all words in file
void Counter::countAlg(std::ifstream& filename)
{
std::string buffer;
while (filename >> buffer)
{
++words_count;
}
}
uint Counter::getCount()
{
return words_count;
}
我需要在给定数量的线程中迭代此向量,并在每个文件中计算字数。我对ThreadsPool的代码不是很清楚,因此我不知道如何在main函数中调用它。我应该在入队功能中传递什么?
(对不起,我的英语)
解决方法
enqueue
的参数传递给std::packaged_task
的构造函数,该构造函数具有以下描述:
类模板std :: packaged_task包装了任何Callable目标(函数,lambda表达式,绑定表达式或其他函数对象),以便可以异步调用它。
由于您已经拥有Counter类,因此可以在allTxtFiles
方法中为每个文件创建一个任务,如下所示:
void Counter::allTxtFiles() {
for (auto& p : bfs::directory_iterator(dir)) {
if (p.path().extension() == ".txt") {
auto fut = theThreadPool.enqueue([path = p.path()]() {
bfs::ifstream ifs(path);
Counter c;
c.countAlg(ifs);
return c.getCount();
});
txt_files[p.path] = fut;
}
}
}
这将填充std::map<bfs::path,std::future<int> txt_files
,然后您可以走动。如果您不希望快速将路径映射到字数统计,也可以填充std::vector<std::pair<bfs::path,std::future<int>>
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。