在循环中重用线程c
作者:互联网
我需要在C程序中并行化一些任务,对并行编程来说是全新的.到目前为止,我通过互联网搜索取得了一些进展,但现在有点卡住了.我想在循环中重用一些线程,但显然不知道如何做我正在尝试的东西.
我从计算机上的两个ADC卡(并行获取)中获取数据,然后我需要对收集的数据(并行处理)执行一些操作,同时收集下一批数据.这是一些伪代码来说明
//Acquire some data, wait for all the data to be acquired before proceeding
std::thread acq1(AcquireData, boardHandle1, memoryAddress1a);
std::thread acq2(AcquireData, boardHandle2, memoryAddress2a);
acq1.join();
acq2.join();
while(user doesn't interrupt)
{
//Process first batch of data while acquiring new data
std::thread proc1(ProcessData,memoryAddress1a);
std::thread proc2(ProcessData,memoryAddress2a);
acq1(AcquireData, boardHandle1, memoryAddress1b);
acq2(AcquireData, boardHandle2, memoryAddress2b);
acq1.join();
acq2.join();
proc1.join();
proc2.join();
/*Proceed in this manner, alternating which memory address
is written to and being processed until the user interrupts the program.*/
}
这是它的主要要点.循环的下一次运行将写入“a”内存地址,同时处理“b”数据并继续交替(我可以获取代码来执行此操作,只是将其取出以防止混乱问题).
无论如何,问题(我确信有些人已经知道)是我第二次尝试使用acq1和acq2时,编译器(VS2012)说“IntelliSense:没有适当的操作符调用类类型的对象( )或转换函数到指针到函数类型“.同样,如果我将std :: thread再次放在acq1和acq2之前,它会显示“错误C2374:’acq1’:重新定义;多次初始化”.
所以问题是,我可以在完成上一个任务后将线程重新分配给新任务吗?我总是等待先前使用线程结束再次调用它,但我不知道如何重新分配线程,因为它在循环中,我不能每次都创建一个新线程(或者如果我可能,这似乎是浪费和不必要的,但我可能会弄错).
提前致谢
解决方法:
最简单的方法是使用std :: function对象的可等待队列.像这样:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <functional>
#include <chrono>
class ThreadPool
{
public:
ThreadPool (int threads) : shutdown_ (false)
{
// Create the specified number of threads
threads_.reserve (threads);
for (int i = 0; i < threads; ++i)
threads_.emplace_back (std::bind (&ThreadPool::threadEntry, this, i));
}
~ThreadPool ()
{
{
// Unblock any threads and tell them to stop
std::unique_lock <std::mutex> l (lock_);
shutdown_ = true;
condVar_.notify_all();
}
// Wait for all threads to stop
std::cerr << "Joining threads" << std::endl;
for (auto& thread : threads_)
thread.join();
}
void doJob (std::function <void (void)> func)
{
// Place a job on the queu and unblock a thread
std::unique_lock <std::mutex> l (lock_);
jobs_.emplace (std::move (func));
condVar_.notify_one();
}
protected:
void threadEntry (int i)
{
std::function <void (void)> job;
while (1)
{
{
std::unique_lock <std::mutex> l (lock_);
while (! shutdown_ && jobs_.empty())
condVar_.wait (l);
if (jobs_.empty ())
{
// No jobs to do and we are shutting down
std::cerr << "Thread " << i << " terminates" << std::endl;
return;
}
std::cerr << "Thread " << i << " does a job" << std::endl;
job = std::move (jobs_.front ());
jobs_.pop();
}
// Do the job without holding any locks
job ();
}
}
std::mutex lock_;
std::condition_variable condVar_;
bool shutdown_;
std::queue <std::function <void (void)>> jobs_;
std::vector <std::thread> threads_;
};
void silly (int n)
{
// A silly job for demonstration purposes
std::cerr << "Sleeping for " << n << " seconds" << std::endl;
std::this_thread::sleep_for (std::chrono::seconds (n));
}
int main()
{
// Create two threads
ThreadPool p (2);
// Assign them 4 jobs
p.doJob (std::bind (silly, 1));
p.doJob (std::bind (silly, 2));
p.doJob (std::bind (silly, 3));
p.doJob (std::bind (silly, 4));
}
标签:c,multithreading,loops,reusability 来源: https://codeday.me/bug/20190923/1815401.html