2013-09-30 48 views
2

我正在使用C++ 11上的线程库来做一些事情。问题是我的线程数量有限(4)。几个线程的多个任务

我会知道如何对付它:

#include <iostream> 
#include <string> 
#include <vector> 
#include <thread> 

#define NUMBER_OF_THREADS 4 

void foo(const std::string& astring) 
{ 
    std::cout << astring << std::endl; 
} 

int main() 
{ 
    std::vector<std::string> list_of_strings(100); 
    // values assigned 
    std::vector<std::thread> list_of_threads(NUMBER_OF_THREADS); 
    for(std::vector<std::string>::const_iterator it_string = list_of_strings.begin() ; it_string != list_of_strings.end() ; ++it_string) 
    { 
     bool check = false; 
     unsigned int = 0; 
     while(!check) // loop which assigns the next task to the first thread ready. 
     { 
      if(check = list_of_threads.at(i).ISFREE()) // how to do ? 
      { 
       list_of_threads.at(i) = thread(&foo,*it_string); 
      } 
      else 
      { 
       i = (i + 1) % NUMBER_OF_THREADS; 
      } 
     } 
    } 
    for(std::vector<std::thread>::iterator it = list_of_threads.begin() ; it != list_of_threads.end() ; ++it) 
     it->join(); // the main thread is waiting for all threads before closing. 
    return 0; 
} 

但我不知道如何检查,如果线程准备一个新的任务或没有。任何想法 ?

+1

德鲁霍尔迄今为止已是最好的答案。忘记使用一些令人讨厌的(并且很可能是bug),“线程管理器循环”来显式管理线程,并将任务排队到池中。 –

+0

@BradTilley:是的,我在我的代码中使用它,我只是在我的问题中编写了#define,因为它更明显:p – Alfred

回答

5

通常的解决方案是将任务存储在共享队列中(由互斥锁和条件变量保护),并让每个线程在完成当前任务时检查其他任务。这样,每个线程都保持忙碌,程序的其余部分可以保持对配置的无知。

+0

谢谢^^将任务存储到共享队列似乎是个好主意,但我该怎么做?有线程管理器的例子吗? – Alfred

3

没有好的内置方式。你可以使用std::async而不是std::thread,它返回一个std::future,你可以查询 - 这在一般情况下可能更可取,因为它完全是你在做的 - 处理工作项目时不需要花费整个操作系统线程的开销。

或者你可以让你的线程发信号通知它已完成(比如说通过std::atomic或更可能是std::condition_variable),然后从主线程中获取.join()以确保其真正终止。

+0

'async'很可怕,可能会被弃用于C++ 14。 –

+0

@ R.MartinhoFernandes出于好奇,为什么'异步'是可怕的? – Sungmin

+0

@Sungmin这是'async'最明显的问题http://chat.stackoverflow.com/transcript/message/8951379#8951379。 –

0

我对std :: thread不熟悉,但假设没有更好的线程类可用,它具有您需要的功能(请参阅Mikes的答案也许),我会建议您编写基于std ::线。 std :: thread会得到一个指向你自己成员函数的函数指针,它设置一个线程正忙的内部标志,然后调用外部提供的函数,然后重置所述标志。添加一个返回标志状态的方法IsBusy(),就完成了。

+0

IsBusy()会提供有意义的信息吗?我可以看到它提供了误报(线程在你提问后很快就会停止)*和*漏报(线程即将开始工作,并且只会在你提出问题后立即设置标志)。 (这甚至假设该标志是一个原子变量) –

+0

@ R.MartinhoFernandes - 是的,这些'线程管理器'循环与状态检查显然是越野车,非明显的越野车或,(很少),只是绝望贫穷性能:(( –

+0

)当然,这绝不是一个准备好使用的解决方案,人们将不得不花费相当多的时间来正确地实施和测试这样的课程。其他答案可能更适合Op描述。 – SvenS