c++ - 在循环c++中重用线程

标签 c++ multithreading loops reusability

我需要在 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.*/
}

这就是它的主要内容。循环的下一次运行将在处理“b”数据时写入“a”内存地址并继续交替(我可以让代码做到这一点,只是将其取出以防止混淆问题)。

无论如何,问题(我相信有些人已经知道了)是我第二次尝试使用 acq1 和 acq2 时,编译器 (VS2012) 说“IntelliSense:调用没有适当的 operator() 或将函数转换为指向函数类型的指针”。同样,如果我再次将 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++ - 在循环c++中重用线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26516683/

相关文章:

c++ - 在对函数指针进行 typedef 时 * 是强制性的吗?

javascript - jquery 如何在(几乎)准确的时间内始终如一地执行动画功能?

loops - Ping 主机名列表并将结果输出到 powershell 中的 csv

c - 如何加速我的代码?

c++ - SendNotifyMessage 不发送正确的消息

c++ - memory_order_seq_cst 和 memory_order_release 的可能排序

c++ - 删除包含 vector 的结构 -- munmap_chunk() : invalid pointer:

c++ - sleep (4000)显示。每 1000 (C++)

c++ - 如何防止任何人窃取我的 shared_ptr?

java - 转换为 ScheduledThreadPoolExecutor