2

我今天刚刚开始使用标准库深入研究多线程。以下是我到目前为止的想法。虽然它原则上是有效的,但它不会在一个线程完成后启动一个新线程,而是在最后 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();

    }
}
4

1 回答 1

2

处理一组执行某些任务的线程的常用方法是启动 X 个线程,然后让每个线程从一个公共队列中选择它的“工作”。在一个非常简单的情况下,您只需简单地,而不是在创建线程的循环中执行i+1and , let be a ,然后执行:i++istd::atomic<int>

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

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

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

于 2013-10-02T19:41:09.323 回答