使用Boost将单线线程转换为多线程
Using boost to turn single thread to multi thread
我正在尝试将代码从单个线程转换为多线程(例如,创建6个线程,而不是1(,同时确保它们都启动和完成,而不会从每个线程中完成任何干扰其他。这是什么方法?我可以做一个为循环创建线程直到i&lt的循环;6?只需添加lock((和unlock((?
添加一个mutex类#include <iostream>
#include <boost/thread.hpp>
#include <boost/date_time.hpp>
void workerFunc()
{
boost::posix_time::seconds workTime(3);
std::cout << "Worker: running" << std::endl;
// Pretend to do something useful...
boost::this_thread::sleep(workTime);
std::cout << "Worker: finished" << std::endl;
}
int main(int argc, char* argv[])
{
std::cout << "main: startup" << std::endl;
boost::thread workerThread(workerFunc);
std::cout << "main: waiting for thread" << std::endl;
workerThread.join();
std::cout << "main: done" << std::endl;
system("pause");
return 0;
}
是的,当然是可能的。由于您不希望它们之间有任何干扰,因此请给他们独特的数据来使用,以便您不需要将对该数据的访问与std::mutex
同步或使其成为std::atomic
。要进一步最大程度地减少线程之间的干扰,请根据std :: hardware_derthuctive_interference_ize。
您可以使用boost :: thread :: hardware_concurrency((获取当前系统上可用的硬件线程的数量,以便您不必进行硬码即可运行的线程数。
可以使用std::ref
传递对线程的引用(否则,线程将获得数据的副本(。
在这里,我创建了一个线程的std::list
和一个数据的std::vector
。
#include <cstdint> // std::int64_t
#include <iostream>
#include <list>
#include <new> // std::hardware_destructive_interference_size
#include <vector>
#include <boost/thread.hpp>
unsigned hardware_concurrency() {
unsigned rv = boost::thread::hardware_concurrency();
if(rv == 0) rv = 1; // fallback if hardware_concurrency returned 0
return rv;
}
// if you don't have hardware_destructive_interference_size, use something like this
// instead:
//struct alignas(64) data {
struct alignas(std::hardware_destructive_interference_size) data {
std::int64_t x;
};
void workerFunc(data& d) {
// work on the supplied data
for(int i = 0; i < 1024*1024-1; ++i) d.x -= i;
for(int i = 0; i < 1024*1024*1024-1; ++i) d.x += i;
}
int main() {
std::cout << "main: startup" << std::endl;
size_t number_of_threads = hardware_concurrency();
std::list<boost::thread> threads;
std::vector<data> dataset(number_of_threads);
// create the threads
for(size_t idx = 0; idx < number_of_threads; ++idx)
threads.emplace_back(workerFunc, std::ref(dataset[idx]));
std::cout << "main: waiting for threads" << std::endl;
// join all threads
for(auto& th : threads) th.join();
// display results
for(const data& d : dataset) std::cout << d.x << "n";
std::cout << "main: done" << std::endl;
}
如果您使用的是C 11(或更高版本(,我建议改用std::thread
。
启动并停止一堆Boost线程
std::vector<boost::thread> threads;
for (int i = 0; i < numberOfThreads; ++i) {
boost::thread t(workerFunc);
threads.push_back(std::move(t));
}
for (auto& t : threads) {
t.join();
}
请记住,join()
不会终止线程,它只等到它们完成。
同步
如果多个线程访问相同的数据,并且其中至少有一个是编写数据,则需要互音。您可以使用MUTEX确保多个线程输入代码的关键部分。示例:
std::queue<int> q;
std::mutex q_mu;
void workerFunc1() {
// ...
{
std::lock_guard<std::mutex> guard(q_mu);
q.push(foo);
} // lock guard goes out of scope and automatically unlocks q_mu
// ...
}
void workerFunc2() {
// ...
{
std::lock_guard<std::mutex> guard(q_mu);
foo = q.pop();
} // lock guard goes out of scope and automatically unlocks q_mu
// ...
}
这可以防止未定义的行为,例如阅读尚未完全编写的队列中的项目。请小心 - 数据竞赛可能会使您的程序崩溃或破坏数据。我经常使用线程消毒剂或Helgrind等工具,以确保我不会错过任何东西。如果您只想将结果传递回主程序,而不需要在线程之间共享数据,则可能需要考虑使用std::promise
和std::future
。
是的,可以使用简单的循环来完成新线程。但是,您必须牢记一些事情:
- 如果线程将在共享数据上运行,则需要使用静音,原子或通过其他方式保护它,以避免数据竞赛和不确定的行为(请记住,即使是诸如
int
之类的原始类型,也必须用一个根据标准(。 - 您将必须确保您最终将在每个产卵线的对象脱离范围之前最终在每个产卵线程上调用
join()
或detach()
,以防止其突然终止。 - 最好在等待工作线程有效使用而不是浪费的时候在主线程上进行一些计算。
- 您通常要在1个线程开始使用一个线程(主线程(开始运行时要衍生1个线程。
- 在C++中使用cURL和多线程
- 多线程双缓冲区
- 为什么我的多线程作业队列崩溃
- 在main()之外初始化std::vector会导致性能下降(多线程)
- 试图创建一个多线程程序来查找0-100000000之间的总素数
- 为什么一个向量上的多线程操作很慢
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 全局变量 多读取器 一个写入器多线程安全?
- boost::文件系统::recursive_directory_iterator多线程安全
- 如何阻止TensorFlow的多线程
- 如何在多线程中正确使用unique_ptr进行多态性?
- 并发/多线程:是否可以以这种方式生成相同的输出?
- sigwait() 在多线程程序中不起作用
- 多线程程序中出现意外的内存泄漏
- 静态 constexpr 类成员变量对多线程读取是否安全?
- 多线程比没有线程C++慢
- 具有 C++11 多线程的特征库
- 使用Boost将单线线程转换为多线程
- 在多线程库中转换future
- 带有std::线程强制转换变量的c++多线程服务器