C++ 基于线程的队列算法

C++ 基于线程的队列算法,c++,multithreading,boost-thread,deque,C++,Multithreading,Boost Thread,Deque,假设有一个指向要执行的任务的指针的std::deque队列,那么确保一次运行的线程数限制在CPU内核数以内的最佳方法是什么?i、 e.任务完成后,后续将启动剩余的任务 我为之前的一篇文章编写了以下代码,现在的问题是我不确定实现我所描述的内容的最佳策略,并且认为这可能值得征求意见 请注意,我上面提到的“std::deque指针队列”在代码中并不是指deque mtask。我不想从这个deque弹出任务,因为我用它来存储以前完成的任务 在程序中,在提示符处键入task p1 p2 p3 p4 p5,

假设有一个指向要执行的任务的指针的std::deque队列,那么确保一次运行的线程数限制在CPU内核数以内的最佳方法是什么?i、 e.任务完成后,后续将启动剩余的任务

我为之前的一篇文章编写了以下代码,现在的问题是我不确定实现我所描述的内容的最佳策略,并且认为这可能值得征求意见

请注意,我上面提到的“std::deque指针队列”在代码中并不是指deque mtask。我不想从这个deque弹出任务,因为我用它来存储以前完成的任务

在程序中,在提示符处键入task p1 p2 p3 p4 p5,然后键入info以检查每个任务的当前状态。请注意,目前所有5项任务几乎同时完成。然而,我真正想要的是第一个2完成(双核机器),然后是下一个2等

这样做的原因是,在实践中,这些任务可能需要几个小时,因此我希望尽快得到第一批结果,以便将它们加载到MATLAB或其他软件中

我希望我把自己和示例代码讲清楚了。我猜thread::hardware_concurrency()涵盖了核心部分的数量

谢谢 A

#包括
#包括
#包括
#包括
使用名称空间std;
课堂任务{
公众:
字符串mname;
布尔完成;
void start()
{
int a=0;
对于(inti=0;i>temp){mm.startTask(temp);}
}
如果(温度比较(“信息”)==0)
{ 
//返回所有已完成和未完成任务的列表

对于(int i=0;i您所描述的是线程池模式,其中有固定数量的线程和一组要使用这些线程执行的任务(#任务>线程)


线程池模式中的条目包含更多信息。您可以编写自己的,也可以使用类似于非官方的内容。

根据定义,一次运行的线程数已经限制为CPU内核数,但我猜您的意思是应该没有准备好的线程,而不是无法获得内核:)@MartinJames是的,据我所知,一个人可以启动比内核更多的线程,操作系统会给每个线程留出运行的时间我需要将运行的线程数限制为内核数,以便充分利用可用的内核,同时最大限度地缩短单个任务结果的完成时间。我不确定我是否理解。如果您希望在双核机箱上快速完成前两个任务,您能不能在线程池中创建两个线程,等等在一个队列上运行?另一个线程安全的出列和一个信号量,或者其他类型的阻塞收集有什么问题?@MartinJames线程安全的出列是我考虑过的,但我不确定如何限制一次运行的线程数,因此发布。现在线程池模式,这正是我需要实现的但是我不知道这个术语。@MartinJames刚才丢了一分钱-我应该在第一个实例中只创建2个线程,他们应该从线程安全的deque中弹出另一个任务,只要它不是空的,然后处理它。:)线程池模式看起来很完美,我不知道这个术语,我很高兴我发布了这个帖子。+1
#include <iostream>  
#include <string>
#include <sstream>
#include <boost/thread.hpp>  

using namespace std;

class task {
public:
    string mname;
    bool completed;
    void start()
    {
        int a = 0;
        for (int i=0 ; i<10000; i++)
        {
            for (int j=0 ; j<100000; j++)
            {
                a= i*2;
            }
        }
        this->completed = true;
    }
    task(string name)
    {
        mname = name;
        completed = false; 
    }
};

class taskManager{
    public:
        boost::thread_group threads;
        void startTask( string name )
        {
            //add new task to vector list           
            mtasks.push_back( task(name) );
            // execute start() on a new thread
            threads.create_thread( boost::bind( &task::start, &mtasks.back()) );
        }
        int tasksTotal()
        {
            return mtasks.size();
        }
        string taskInfo(int i)
        {
            string compstr("Not Completed");
            if ( mtasks.at(i).completed == true )
            {
                compstr = "Completed";
            }
            return mtasks.at(i).mname + " " + compstr; 
        }
    private:
        deque<task> mtasks; 
};

int main(int argc, char* argv[])  
{
    string cmd, temp;
    stringstream os;
    bool quit = false;
    taskManager mm;

    cout << "PROMPT>";

    while (quit == false)
    {
        //Wait for a valid command from user
        getline(cin,cmd);

        // Reset stringstream and assign new cmd string
        os.clear(); 
        os << "";
        os << cmd;
        //parse input string
        while (os >> temp) 
        {               
            if ( temp.compare("task") == 0 )
            {
                while (os >> temp) { mm.startTask( temp ); }                     
            }
            if ( temp.compare("info") == 0 )
            { 
                // Returns a list of all completed and not completed tasks
                for (int i = 0; i<mm.tasksTotal(); i++)
                {
                    cout << mm.taskInfo(i).c_str() << endl;
                }                           
            }
            if ( temp.compare("quit") == 0 ){ quit = true; }
        }

        cout << "PROMPT>";
    }

    mm.threads.join_all();      

    return 0;  
};