std::thread и ввод с помощью std::cin в приложении opengl

Я использую поток, чтобы предоставить пользователю оболочку в приложении OpenGL.

Моя проблема в том, что я не могу отменить поток в конце основного цикла, потому что std::thread не предоставляет метод отмены, а мой поток заблокирован вызовом std::cin >> var, поэтому я не могу использовать логическое значение для сохранить тот факт, что поток должен остановиться.

Я хотел бы знать, есть ли хороший способ использования std::cin в потоке (std::thread) или альтернативные решения.


person Pierre Emmanuel Lallemant    schedule 02.11.2013    source источник
comment
ваша тема отсоединена или присоединена   -  person aaronman    schedule 02.11.2013
comment
Никто. Если я вызову thread.join(), приложение будет ждать окончания потока, но поток будет заблокирован вызовом std::cin. Я могу не понять, что такое отсоединение потока (отключение текущего процесса, как это делает fork()?)   -  person Pierre Emmanuel Lallemant    schedule 02.11.2013
comment
Похоже, что он присоединился, после создания потока в С++ 11 вы либо вызываете соединение, либо отсоединяете его.   -  person aaronman    schedule 02.11.2013
comment
вам нужно читать, используя >>? Может помочь асинхронный вызов ввода-вывода (если он не стандартизирован).   -  person Yakk - Adam Nevraumont    schedule 02.11.2013
comment
Да, я использую >>, но кое-что обнаружил: когда я отсоединяю поток в конструкторе ThreadClass, который я написал, у меня возникают проблемы; когда я отсоединяю его в основном цикле, он работает случайным образом: если поток начинает выполняться до того, как он будет отсоединен, он не работает, в другом случае он работает.   -  person Pierre Emmanuel Lallemant    schedule 02.11.2013


Ответы (1)


Что вам может понадобиться, так это прерывающий поток, С++ не дает вам его, но параллелизм C++ в действии имеет простую реализацию. Это может быть то, что вам нужно. Не удивлюсь, если он есть и у boost, поскольку книга написана сопровождающим библиотеки потоков.

class interrupt_flag
    {
    public:
    void set();
        bool is_set() const;
    };
    thread_local interrupt_flag this_thread_interrupt_flag;
    class interruptible_thread
    {
        std::thread internal_thread;
        interrupt_flag* flag;
    public:
        template<typename FunctionType>
        interruptible_thread(FunctionType f)
        {
            std::promise<interrupt_flag*> p;
            internal_thread=std::thread([f,&p]{
                    p.set_value(&this_thread_interrupt_flag);
                    f(); 
                });
        flag=p.get_future().get();
    }
    void interrupt()
    {
        if(flag) {
            flag->set();
        }
    } 
};  

Теперь вы можете легко отменить поток из вашего файла main. Даю ссылку на книгу но весь код из книги тоже в сети бесплатно. Вот ссылка на исходный код в книге, хотя без книга, которая является большим чтением BTW.

person aaronman    schedule 02.11.2013
comment
Спасибо ! Это то, что мне нужно. - person Pierre Emmanuel Lallemant; 02.11.2013
comment
@KerrekSB: это показывает мне, что мне нужен экземпляр в моем потоке, который отправит исключение. - person Pierre Emmanuel Lallemant; 02.11.2013
comment
internal_thread=std::thread([f,&p] ... -> Мне нужно отправить указатель, указывающий на указатель, указывающий на флаг, в мой поток, и поток инициализирует адрес. - person Pierre Emmanuel Lallemant; 02.11.2013
comment
Флаг не может быть прочитан неинициализированным из-за проверки того, что он инициализирован, что касается того, как это поможет, я должен признать, что я не читал его слишком тщательно, но вспомнил, что видел это в книге, я думал, что все, что ему нужно было в состоянии сделать, это прервать поток из основного - person aaronman; 02.11.2013
comment
@KerrekSB, вы знаете, что реализация может быть не завершена на 100%, когда я смотрю на нее. - person aaronman; 02.11.2013
comment
@PierreEmmanuelLallemant кстати, похоже, что в библиотеке потоков boost есть прерываемый поток, поэтому вы можете просто использовать его, поскольку он, вероятно, более полный - person aaronman; 02.11.2013
comment
У меня странный результат, я использовал тот же класс, что и вы написали. Случайным образом программа блокируется и ждет ввода пользователя (std::cin ›› var), я перезапускаю ее, и тогда активна только часть opengl, а не ввод (это совершенно случайно). Кто-нибудь знает, почему это пб происходит? - person Pierre Emmanuel Lallemant; 02.11.2013
comment
Я написал std::cin >> str; в своем коде, извините за ошибку в моем комментарии. Но я не знаю, почему он блокирует 2 потока. Кажется, что поток не создается, но иногда выполняет функцию в основном цикле. - person Pierre Emmanuel Lallemant; 02.11.2013
comment
@PierreEmmanuelLallemant Ну, на этом этапе вам следует просто задать новый вопрос или хотя бы опубликовать некоторый код, так как я ответил на первый вопрос - person aaronman; 02.11.2013
comment
Я заменил std::thread на phtread, потому что у меня с ним проблем нет. Я задам новый вопрос через несколько минут. Спасибо за вашу помощь. - person Pierre Emmanuel Lallemant; 02.11.2013