Я пытаюсь запускать функцию run () каждые 5 секунд без остановки цикла while () (параллельно). Как я могу это сделать ? заранее спасибо

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

    using namespace std;

    void run() 
    {
        this_thread::sleep_for(chrono::milliseconds(5000));

        cout << "good morning" << endl;
    }


    int main()
    {
        thread t1(run);
        t1.detach();

        while(1)
        {
            cout << "hello" << endl;

            this_thread::sleep_for(chrono::milliseconds(500));
        }

        return 0;
    }
1
user6200763 11 Фев 2020 в 09:56

2 ответа

Лучший ответ

Просто вызовите свою функцию запуска в отдельной функции потока, как показано ниже. Это нормально для тебя?

void ThreadFunction()
{
    while(true) {
        run();
        this_thread::sleep_for(chrono::milliseconds(5000));
    }
}

void run() 
{
    cout << "good morning" << endl;
}


int main()
{
    thread t1(ThreadFunction);
    t1.detach();

    while(1)
    {
        cout << "hello" << endl;

        this_thread::sleep_for(chrono::milliseconds(500));
    }

    return 0;
}
0
idris 11 Фев 2020 в 08:26

В вашей функции main важно понимать, что делает каждый поток.

  1. Основной поток создает std::thread с именем t1
  2. Основная нить продолжается и отсоединяет нить
  3. Основной поток выполняет ваш while цикл, в котором он: < UL>
  4. печатает привет
  5. спит в течение 0,5 секунд
  6. Основной поток возвращает 0, ваша программа завершена.

В любое время из пункта 1 нить t1 спит в течение 5 секунд, а затем печатает доброе утро. Это происходит только один раз! Кроме того, как указывает @Fareanor, std::cout не является потокобезопасным, поэтому доступ к нему с помощью основного потока и потока t1 может привести к гонке данных.

Когда основной поток достигает точки 4 (на самом деле это никогда не происходит, потому что ваш цикл while бесконечен), ваш поток t1 мог завершить свою задачу или нет. Представьте себе потенциальные проблемы, которые могут возникнуть. В большинстве случаев вы захотите использовать std::thread::join().

Чтобы решить вашу проблему, есть несколько альтернатив. В дальнейшем мы будем предполагать, что выполнение функции run без std::this_thread::sleep_for незначительно по сравнению с 5 секундами, согласно комментарию @Landstalker. Время выполнения run составит 5 секунд плюс незначительное время.

Как предлагается в комментариях, вместо выполнения функции run каждые 5 секунд, вы можете просто выполнять тело run каждые 5 секунд, поместив цикл while внутри этой функции:

void run() 
{
    while (true)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(5000));
        std::cout << "good morning" << std::endl;
    }
}

int main()
{
    std::thread t(run);
    t.join();
    return 0;
}

Если по какой-то причине вам действительно нужно выполнять функцию run каждые 5 секунд, как указано в вашем вопросе, вы можете запустить функцию-оболочку или лямбду, которая содержит цикл while:

void run() 
{
    std::this_thread::sleep_for(std::chrono::milliseconds(5000));
    std::cout << "good morning" << std::endl;
}

int main()
{
    auto exec_run = [](){ while (true) run(); };
    std::thread t(exec_run);
    t.join();
    return 0;
}

Как примечание, лучше избегать using namespace std .

3
mfnx 11 Фев 2020 в 14:03