Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Остановка рабочей функции потока


Автор: cppGhost 8.8.2016, 12:10
День добрый. Задумался над таким вот вопросом. Допустим, у меня есть две функции get(StopObj obj) и process(StopObj obj).
Эти две функции я запускаю из нескольких потоков. Сам StopObj obj это некий сигнал функциям, что работу стоит прервать. Делают ли так вообще? При этом достаточно ли в StopObj добавить флаг типа bool, по которому эти функции будут определять нужно ли преждевременно завершать работу? 

Автор: azesmcar 8.8.2016, 12:51
Делают. посмотри в .net например https://msdn.microsoft.com/en-us/library/system.threading.cancellationtoken(v=vs.110).aspx.
В одной функции делается так:
Код

while (!token.is_cancellation_requested())
{
    // do some work
}

в другой вызывается cancel
Код

token.cancel();


Добавлено через 4 минуты и 18 секунд
реализуется на обычном атомарном bool

Автор: cppGhost 8.8.2016, 14:16
Ага. Единственное, я написал функции, куда передаётся объект по значению. Правильнее ведь, как я понимаю, передавать по ссылке?

Автор: azesmcar 8.8.2016, 14:56
какой объект ? не совсем понял.

Автор: cppGhost 8.8.2016, 15:02
Код

get(StopObj obj)

должно ведь быть
Код

get(StopObj &obj)


или наборот тут лучше по значению, чтобы исключить возможность изменения объекта в ходе выполнения функции?

Автор: azesmcar 8.8.2016, 15:41
Тебе же нужно как раз, чтобы все функции разделяли этот объект. Если передать по значению, тогда вызов cancel() на одном из них, на состояние другого никак не повлияет.

Добавлено через 7 минут и 34 секунды
вот пример в примитивном виде.
Код

#include <iostream>
#include <thread>
#include <atomic>

class cancellation_token
{
public:
    cancellation_token()
        :cancellation_requested_(false)
    {
    }

    bool is_cancellation_requested() const
    {
        return cancellation_requested_.load(std::memory_order_acquire);
    }

    void cancel()
    {
        cancellation_requested_.store(true, std::memory_order_release);
    }
private:
    std::atomic_bool cancellation_requested_;
};

void process(cancellation_token& token)
{
    static int x = 0;
    while (!token.is_cancellation_requested())
    {
        std::cout << "x = " << ++x << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

int main()
{
    cancellation_token token;
    std::thread th(process, std::ref(token));
    std::cin.get();
    token.cancel();
    th.join();
}

Автор: cppGhost 8.8.2016, 15:59
Всё, понял. Большое спасибо

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)