简体   繁体   English

使用条件变量对向量的向量进行并行排序?

[英]Sort a vector of vectors in parallel using a conditional variable?

I am trying to sort a NxN vector of vectors in parallel by dispatching N threads for each vector. 我试图通过为每个向量分派N个线程来对向量的NxN个向量进行并行排序。 I want to display the vector of vectors every time each vector within the vector of vectors has been sorted. 我想每次对向量中的每个向量进行排序时都显示向量。 Please see example below. 请参见下面的示例。

Initially 原来

2,1,3,4
1,3,2,4
3,4,1,2
3,2,1,4

Sorting . 排序。 . Display 显示

1,2,3,4
1,2,3,4
1,4,3,2
2,3,1,4

. . Sorting . 排序。 .

1,2,3,4
1,2,3,4
1,3,4,2
2,1,3,4

... and so on.. ... 等等..

I have some executable code to do this sequentuially and I have tried to do this using a conditional variable but I can't get it to work with the conditional variable at all. 我有一些可执行的代码可以顺序执行此操作,并且我尝试使用条件变量来执行此操作,但是我根本无法使其与条件变量一起使用。

Below is the sequential code which is working in terms of sorting the vector of vectors but it can't produce the display that I desire. 以下是按顺序对向量进行排序的顺序代码,但无法产生我想要的显示。

#include<iostream>
#include<vector>
#include <ctime> 
#include <random>


std::vector<int> row;
std::vector<std::vector<int>> block;
int cols = 10;
auto rng = std::default_random_engine{};


void init()
{

        srand((unsigned)time(0));
        for (int i = 0; i < 10; i++)
        {
            int j;
            j = (rand() % 100) + 1;
            row.push_back(j);
    }

            for (int i = 0; i < 10; i++)
            {

                std::vector<int> y;
                std::shuffle(std::begin(row), std::end(row), rng);
                y = row;
                block.push_back(y);
            }

    for (int i = 0; i < cols; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            std::cout << block[i][j] << ", "; 

        }
        std::cout << "\n";
    }
}

void Sort(std::vector<int> &Row)
{

        for (int i = 0; i < cols; i++)
        {
            for (int j = 0; j < i; j++)
            {
                if (Row[i] < Row[j])
                {
                    int temp = Row[i];
                    Row[i] = Row[j];
                    Row[j ] = temp;
                }
            }
        }

}

void display()
{
    for (int i = 0; i < cols; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            std::cout << block[i][j] << ", ";

        }
        std::cout << "\n";
    }
}


int main() {

    std::cout << "test\n";
    init();
    std::cout << "\n";
    std::cout << "Sorting";
    std::cout << "\n";
    for(int i =0; i < cols; i++)    
        Sort(block[i]);
    std::cout << "\n";
    display();
    std::cout << "Sorted";
    getchar();
}

The output for the above code is as follows 上面代码的输出如下

98, 15, 13, 10, 44, 63, 85, 93, 39, 43,
93, 10, 15, 13, 43, 44, 39, 63, 85, 98,
93, 13, 63, 15, 43, 85, 98, 39, 44, 10,
44, 98, 39, 85, 13, 10, 63, 43, 93, 15,
10, 98, 63, 93, 85, 44, 39, 15, 13, 43,
63, 39, 44, 98, 93, 15, 43, 85, 13, 10,
43, 63, 93, 44, 15, 39, 10, 85, 98, 13,
39, 85, 13, 63, 44, 98, 93, 43, 10, 15,
39, 44, 85, 63, 43, 93, 98, 10, 15, 13,
15, 43, 44, 93, 85, 39, 63, 10, 98, 13,

Sorting

10, 13, 15, 39, 43, 44, 63, 85, 93, 98,
10, 13, 15, 39, 43, 44, 63, 85, 93, 98,
10, 13, 15, 39, 43, 44, 63, 85, 93, 98,
10, 13, 15, 39, 43, 44, 63, 85, 93, 98,
10, 13, 15, 39, 43, 44, 63, 85, 93, 98,
10, 13, 15, 39, 43, 44, 63, 85, 93, 98,
10, 13, 15, 39, 43, 44, 63, 85, 93, 98,
10, 13, 15, 39, 43, 44, 63, 85, 93, 98,
10, 13, 15, 39, 43, 44, 63, 85, 93, 98,
10, 13, 15, 39, 43, 44, 63, 85, 93, 98,
Sorted

The multi-threaded approach that I have taken below is not working as expected. 我在下面采用的多线程方法未按预期工作。 I have tried a number of things but to no success. 我尝试了很多事情,但没有成功。

#include<iostream>
#include <thread>
#include<vector>
#include <ctime> 
#include <mutex>
#include<chrono>
#include <algorithm>
#include <random>
#include <deque>
#include <condition_variable>

std::deque<int> q;
std::mutex mu;
std::condition_variable cond;
int count = 4;
std::vector<int> x{ 5,2,1,3,4 };
std::vector<std::vector<int>> xx;
void init() {
    for (int i = 0; i < 5; i++)
    {
        xx.push_back(x);
    }
}

void display()
{
    for (int i = 0; i < xx.size(); i++)
    {
        for (int j = 0; j < xx[i].size(); j++)
        {
            std::cout << xx[i][j] << " ,";
        }
        std::cout << "\n";
    }

}

bool isSorted(int z)
{
    for (int i = 0; i < 5; i++)
    {
        if (xx[z][i] > xx[z][i + 1])
            return false;
    }
    return true;
}

void function_1(int &row)
{

    while (!isSorted(row))
    {
        std::unique_lock<std::mutex> locker(mu);
        for (int i = 0; i < 4; i++)
        {
            if (xx[row][i] > xx[row][i + 1])
            {
                int temp = xx[row][i];
                xx[row][i] = xx[row][i + 1];
                xx[row][i + 1] = temp;
            }
        }
        count--;
        locker.unlock();
        cond.notify_one();
        std::this_thread::sleep_for(std::chrono::seconds(2));

    }
}

void function_2() {
    int data = 0;
    while (data != 1)
    {
        std::unique_lock<std::mutex> locker(mu);
        cond.wait(locker, []() {return (count == 0); });
        q.clear();
        display();
        count = 4;
        locker.unlock();

    }
}

int main()
{
    init();
    for (int i = 0; i < 4; i++) {
        std::thread *t1 = new std::thread(function_1, std::ref(i));
    }
    std::thread t2(function_2);
    //  t2.join();
    std::cout << " all threads done";
    getchar();
}

The output is like this (when compiled with g++ and c++11 standards set): 输出是这样的(当使用g ++和c ++ 11标准集编译时):

main.cpp: In function 'void display()':
main.cpp:27:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (int i = 0; i < xx.size(); i++)
                     ~~^~~~~~~~~~~
main.cpp:29:27: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for (int j = 0; j < xx[i].size(); j++)
                         ~~^~~~~~~~~~~~~~
main.cpp: In function 'int main()':
main.cpp:89:22: warning: unused variable 't1' [-Wunused-variable]
         std::thread *t1 = new std::thread(function_1, std::ref(i));
                      ^~
terminate called without an active exception
 all threads done5 ,2 ,1 ,3 ,4 ,
5 ,2 ,1 ,3 ,4 ,
2 ,1 ,3 ,4 ,5 ,
2 ,1 ,3 ,4 ,5 ,
1 ,2 ,3 ,4 ,5 ,

Here's the demo . 这是演示

The biggest issue you had was to pass i from main as a reference. 您遇到的最大问题是将main的i用作参考。 All the threads would share the 4 that the loop exited with. 所有线程将共享循环退出时使用的4

for (int i = 0; i < 4; i++) {
    std::thread *t1 = new std::thread(function_1, std::ref(i)); //same i !!
}

and then: 接着:

void function_1(int &row)...

Also not that i+1 is 5 before you exit the loop so it is out of range: 同样不是在退出循环之前, i+1是5,所以它超出了范围:

for (int i = 0; i < 5; i++)
{
    if (xx[z][i] > xx[z][i + 1])
        return false;
}

Then, as was pointed out, it is just a matter of joining the threads to wait for a finish. 然后,正如所指出的,仅是加入线程以等待完成的问题。 This seems to work ok but I would have done this with a class so there would be no globals. 这似乎工作正常,但我会在一个类中完成此操作,因此不会有全局变量。

I left the includes out... 我忽略了包含...

std::mutex mu;
std::vector<int> x{ 5,2,1,3,4 };
std::vector<std::vector<int>> xx;

void init() {
    for (int i = 0; i < 5; i++)
    {
        xx.push_back(x);
    }
}

void display( int in )
{
    for (size_t i = 0; i < xx.size(); i++)
    {
        for (size_t j = 0; j < xx[i].size(); j++)
        {
            std::cout << xx[i][j] << ", ";
        }
        std::cout << std::endl;
    }
    std::cout << " id: " << in << "\n";
}

bool isSorted( int z )
{
    for (size_t i = 0; i < 4; i++)
    {
        if (xx[z][i] > xx[z][i + 1])
            return false;
    }
    return true;
}

void function_1( int row )
{
    for( ; ! isSorted(row); )
    {
        for (int i = 0; i < 4; i++)
        {
            if (xx[row][i] > xx[row][i + 1])
            {
                int temp = xx[row][i];
                xx[row][i] = xx[row][i + 1];
                xx[row][i + 1] = temp;
            }
        }
        std::unique_lock<std::mutex> locker(mu);
        display( row );
        locker.unlock( );
    }
    std::unique_lock<std::mutex> locker(mu);
    std::cout << "end: " << row << std::endl;
    locker.unlock( );

}

int main()
{
    std::vector< std::thread* > threads;
    init();
    for (int i = 0; i < 4; i++)
    {
        std::unique_lock<std::mutex> locker(mu);
        threads.push_back( new std::thread( function_1, i ) );
        std::cout << "started: " << i << std::endl;
        locker.unlock( );
    }
    for( auto thread : threads )
        thread->join( );

    std::cout << " all threads done";
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM