Потоки, выполняющие операцию в секунду - PullRequest
0 голосов
/ 03 октября 2018

Я пытаюсь создать параллельный код, где я выполняю функцию в секунду, эта функция печатает символ и ждет секунду в этом потоке.Я ожидаю, что поведение будет печатать каждый символ за другим, но этого не происходит, вместо этого он печатает все символы выполнения внутреннего цикла.Я не уверен, связано ли это с операцией ввода-вывода или чем-то подобным.

Я также попытался создать массив потоков, в котором каждый поток создается при выполнении внутреннего цикла, ноПоведение повторяется, даже если не вызывать join().Что может быть не так с кодом?

Следующий код - это то, что я пытался сделать, и я использовал часы, чтобы посмотреть, ожидает ли он правильное количество времени

#include <iostream>
#include <thread>
#include <chrono>
#include <string>

void print_char();

int main() {

    using Timer = std::chrono::high_resolution_clock;
    using te    = std::chrono::duration<double>;
    using s     = std::chrono::seconds;

    te interval;

    for (int i = 0; i < 100; i++) {
        auto  a = Timer::now();
        for (int j = 0; j < i; j++) {

            std::thread t(print_char);
            t.join();
        }
        auto b = Timer::now();
        interval = b-a;

        std::cout << std::chrono::duration_cast<s>(interval).count();
        std::cout << std::endl;
    }

        return 0;
}

void print_char() {
    std::cout << "*";
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Я ожидаю, что я буду печатать каждый символ за другим, но этого не происходит, вместо этого он печатает все символы внутреннего цикла.

Вам необходимо очистить выходной поток, чтобы увидеть текст:

std::cout << "*" << std::flush;

std::endl содержит вызов std::flush, и поэтому вы видите целые строки, которые будут отображаться послеВнутренний цикл завершен.Ваши потоки добавляют символы '*' раз в секунду, вы просто не увидите их добавление, пока поток не будет очищен.

0 голосов
/ 03 октября 2018

Рассмотрим код

std::thread t(print_char);
t.join();

Первая строка создает и запускает поток.Во второй строке сразу дождитесь окончания потока.Это делает вашу программу последовательной , а не параллельной.Фактически, это ничем не отличается от вызова функции напрямую вместо создания потока.

Если вы хотите, чтобы поток работал параллельно и независимо от вашего основного потока, у вас должен быть цикл в самой функции потокавместо.Возможно, что-то вроде

std::atomic<bool> keep_running = true;

void print_char() {
    while (keep_running) {
        std::cout << "*";
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

Затем в функции main вы просто создаете поток и делаете что-то еще, пока не захотите завершить поток.

std::thread t(print_char);

// Do something else...

keep_running = false;
t.join();

InЧто касается вашего текущего кода, он действительно ничем не отличается от

for (int i = 0; i < 100; i++) {
    auto  a = Timer::now();
    for (int j = 0; j < i; j++) {
        print_char();
    }
    auto b = Timer::now();
    interval = b-a;

    std::cout << std::chrono::duration_cast<s>(interval).count();
    std::cout << std::endl;
}
...