【问题标题】:How can I make sure there are a given number of threads at all times? (Also, is this a good usage of threads?)如何确保始终有给定数量的线程? (另外,这是线程的好用法吗?)
【发布时间】:2013-10-09 06:55:15
【问题描述】:

我今天刚刚开始使用标准库深入研究多线程。以下是我到目前为止的想法。虽然它在原则上是有效的,但它不会在一个线程完成后启动一个新线程,而是在最后 4 个线程完成后启动 4 个线程,因此如果任务花费的时间不相等,那么效率不是很高。此外,如果他们没有按正确的顺序完成,他们必须等待后续工作完成,直到他们的结果被评估。

我怎样才能实现始终拥有 4 个线程(直到工作用完)?我认为您需要使用某种观察器功能,但我看不出没有信号/插槽是如何实现的。如果您能指出正确的在线手册,我也很高兴。

另外,由于我在今天之前没有使用多处理的经验,请告诉我我可能在哪里使用了不好的做法。

提前谢谢你!

麦片


这是线程任务:

void burn_task(MyClass* obj)
{
    //computationally intensive
    obj->burn();
}

这就是它的名称:

void getsStuffDone()
{
    //initialise everything
    int samples = 1000;    
    int num_threads = 4;

    std::vector<MyClass*> myclasslist;
    std::vector<std::thread*> threadlist;

    myclasslist.resize(num_threads);
    threadlist.resize(num_threads);

    int i = 0;

    //do the work
    while(i+1<samples)
    {
        //current_num_threads = min(num_threads, num_tasks_left)
        int current_num_threads = (samples-i-1>num_threads)? num_threads : samples-i-1;

        //create threads
        for(int t=0; t<current_num_threads; ++t)
        {
            myclasslist[t] = new MyClass(other_parameters,i+1); //i+1 so seed is never zero
            threadlist[t] = new std::thread(burn_task, myclasslist[t]);
            ++i;
        }

        //wait to finish, evaluate and clean up (delete)
        for(int t=0; t<current_num_threads; ++t)
        {
            threadlist[t]->join();

            useResultsContainedWithin(myclasslist[t])

            delete myclasslist[t];
            delete threadlist[t];
        }

        threadlist.clear();

    }
}

【问题讨论】:

    标签: c++ multithreading std standard-library


    【解决方案1】:

    处理一组执行某些任务的线程的常用方法是启动 X 个线程,然后让每个线程从一个公共队列中选择它的“工作”。在一个非常简单的情况下,您可以简单地,而不是在创建线程的循环中执行 i+1i++,让 i 成为 std::atomic&lt;int&gt;,然后执行以下操作:

    void some_thread_function()
    {
      for(;;)
      {
         int work_on = i.fetch_add(1);     // "work_on = i++;"
         if (work_on >= samples)
            break;
         ... // do actual work
      }
    }
    

    在更复杂的情况下,您将有一个等待队列,其中包含更复杂的数据类型来描述要完成的“工作”。

    这意味着您始终拥有“正确”数量的线程,并且没有创建/拆除线程的开销(如果线程运行了相当长的时间(十分之一秒或更长时间),这不是问题无论如何,但对于“短”运行时间,这很可能是一个因素。

    【讨论】:

    • 好吧,我对原子数据类型还不是很熟悉。我应该将对同一个 atomic 的引用传递给所有线程吗?
    • @GuyGreer:那是“我决定用不同的措辞留下的东西”。
    • 不,在这种情况下,原子是一个全局变量——我想引用也可以——无论哪种方式,它都差不多。
    猜你喜欢
    • 2014-08-26
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    • 2021-02-08
    • 2011-02-28
    • 1970-01-01
    • 2010-09-22
    • 1970-01-01
    相关资源
    最近更新 更多