【问题标题】:How to implement threads to sort a vector of vectors synchronously?如何实现线程以同步对向量进行排序?
【发布时间】:2019-06-15 07:32:07
【问题描述】:

我正在创建一个包含整数向量的向量,其想法是通过调用带有线程的冒泡排序来对每个整数向量进行排序,然后打印执行时间。

我试图在每次迭代中实现一个线程但不起作用


vector<int> bubbleSort(vector<int>);

void asynchronousSort(vector<vector<int>> pool){
    double executionTime;

    clock_t tStart = clock();
    for(int i = 0; i < pool.size(); i++){
        thread t (bubbleSort, pool[i]);
        t.join();
    }

    executionTime = (double)(clock() - tStart)/CLOCKS_PER_SEC;
    cout << "Time :" << executionTime<< "s." << endl ;
}

void synchronousSort(vector<vector<int>> pool){
    double executionTime;
    clock_t tStart = clock();

    for(int i = 0; i < pool.size(); i++){
        pool[i] = bubbleSort(pool[i]);
    }

    executionTime = (double)(clock() - tStart)/CLOCKS_PER_SEC;
    cout << "Time :" << executionTime<< "s." << endl ;
}

int main(int argc, const char * argv[]) {

    int selectMethod;
    vector<vector<int>> pool(10);
    //Create 10 lists with 10000 numbers in decrement.
    for (int i = 0; i < 10; i++) {
        vector<int> temp;
        for(int j = 10000; j > 0; j--){
            temp.push_back(j);
        }
        pool.push_back(temp);
    }

    cout << "Select method 1)Asynchronously. 2)Synchronously. (1/2): ";
    cin >> selectMethod;

    if(selectMethod == 1){
        asynchronousSort(pool);
    }else{
        synchronousSort(pool);
    }
    return 0;
}

这两种方法所用的时间相同,而 sinchronousSort 必须更快。

【问题讨论】:

  • Related: 除非你对一些很小的东西进行排序(我所说的很小,我的意思是可能有十几个槽),否则“必须更快”和“冒泡排序”这两个词永远不会在同一个算法中重合,除非“从不使用”一词在后者之前。也就是说,您的函数名称是反对的。异步应该是线程的,同步应该是直接调用的。你应该站起来一个线程向量,每个线程都得到一个要排序的向量,然后在它们都站起来后将它们 all 加入。或者更好的是,使用池和输入队列。

标签: c++ multithreading asynchronous threadpool synchronous


【解决方案1】:

您需要在循环后保留threads 和join

void asynchronousSort(vector<vector<int>> pool){
    double executionTime;
    vector<thread> threads;

    clock_t tStart = clock();
    for(int i = 0; i < pool.size(); i++){
        threads.emplace_back(bubbleSort, pool[i]); // make threads directly inside the vector
                                                   // saves having to std::move them
    }
    for(thread & t:threads) // now that all the threads are up (and maybe running), join them
    {
        t.join();
    }
    // now we can get the execution time
    // note: unless pool is large you may miss it. 
    executionTime = (double)(clock() - tStart)/CLOCKS_PER_SEC;
    cout << "Time :" << executionTime<< "s." << endl ;
}

请注意,这并不是真正的线程池。线程池是您保留并分配作业的线程池。这只是一堆threads。另请注意,如果线程池需要穿着红色和黑色并与观众交谈,那么你就有一个真正的问题。立即寻求帮助。

【讨论】:

    【解决方案2】:

    如果您有支持执行策略的 C++17 编译器(如 VS2017),则可以选择使用std::for_each(std::execution::par, ...

    #include <algorithm>
    #include <execution>
    
    void asynchronousSort(vector<vector<int>>& pool) {
        std::for_each(std::execution::par, pool.begin(), pool.end(), [](auto& v) {
            // used std::sort instead
            std::sort(v.begin(), v.end());
        });
    }
    

    【讨论】:

      【解决方案3】:

      在您的 for 循环中,您等待线程完成 (t.join()),因此不会同时进行排序。

      for(int i = 0; i < pool.size(); i++){
              thread t (bubbleSort, pool[i]);
              t.join();
          }
      

      改用detach(),然后在函数返回之前等待所有线程(例如,将线程*存储在一个向量中,然后将所有线程加入一个for循环)。

      也就是说,线程创建需要时间,因此它可能没有您想象的快速操作那么快。如果这是针对 Windows 的,您可以使用我的 Threadpool API 类,记录在 here

      【讨论】:

      • 同意问题。不同意解决方案。如果提问者detaches,程序在线程完成之前退出的可能性很大。为需要它的边缘情况保存detach,将threads 存储在vector 中,并在它们全部启动并运行后加入它们。
      • 正确,添加评论。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-15
      • 2011-12-12
      • 1970-01-01
      • 1970-01-01
      • 2011-10-03
      • 2016-04-26
      • 1970-01-01
      相关资源
      最近更新 更多