Что может вызывать неопределенное поведение в этой реализации сортировки сна? - PullRequest
0 голосов
/ 02 ноября 2018

Чтобы узнать о многопоточности в C ++, я сделал эту реализацию сна-сортировки. В большинстве случаев это работает правильно. Однако, возможно, один из каждых пятнадцати или около того запусков, вектор, возвращенный моей функцией сортировки сна, будет содержать некоторые значения мусора. Кто-нибудь знает, что может быть причиной этого?

Вот скриншот моего вывода: Garbage output

Вот мой код:

#include <stdio.h>
#include <thread>
#include <chrono>
#include <vector>

std::vector<unsigned int> sleepSort(std::vector<unsigned int> toSort){
    //vector to hold created threads
    std::vector<std::thread> threadList;
    //vector to hold sorted integers
    std::vector<unsigned int> sorted;

    //create a thread for each integer, n, in "toSort" vector
    //each thread sleeps for n seconds then adds n to "sorted" vector
    for(int i = 0; i < toSort.size(); i++){
        threadList.push_back(
            std::thread(
              [](int duration, std::vector<unsigned int>& v){
                std::this_thread::sleep_for((std::chrono::seconds)duration);
                v.push_back(duration);
                }, toSort.at(i), std::ref(sorted)
              )
            );
    }

    //wait for each thread to finish before returning sorted
    for(auto& thread : threadList){
        thread.join();
    }
    return sorted;
}

int main(int argc, char **argv)
{
    std::vector<unsigned int> v {5, 14, 6, 12, 17, 3, 15, 4, 10, 1, 
                                 2, 5, 7, 8, 9, 13, 11, 11, 11, 16
                        };

    printf("Unsorted:\n");
    for(int i = 0; i < v.size(); i++)
        printf("%d\n", v.at(i));

    printf("Sorting...\n");

    v = sleepSort(v);

    printf("Sorted:\n");
    for(int i = 0; i < v.size(); i++)
        printf("%d\n", v.at(i));

    system("PAUSE");
    return 0;
}

1 Ответ

0 голосов
/ 02 ноября 2018

Ничто не мешает двум потокам вызывать push_back одновременно или в одно и то же время. Вам нужен мьютекс или какая-то другая форма синхронизации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...