2017-02-16 6 views
0

Можно ли вызвать функцию joinable() внутри цикла while, чтобы проверить, был ли запрос на соединение в потоке или есть ли какие-либо побочные эффекты, которые я сейчас не рассматриваю?Тест, если соединение было вызвано

+1

", чтобы проверить, есть ли запрос на соединение в потоке" - это не то, что joinable() сообщает вам. –

+2

В стандарте для потока не существует способа проверить и посмотреть, вызвано ли на нем 'join'. Если вы хотите завершить поток, вы будете 'condition_variable' или' atomic '. – NathanOliver

+0

Спасибо. Использование condition_variable и atomic отлично работает. – Gustavo

ответ

1

Законно ли это вызвать joinable() функции внутри цикла в то время как нити, чтобы проверить, есть ли запрос на подключение на резьбе или есть какие-либо побочные эффекты, я не считаю, на данный момент?

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

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

Так что если один поток вызывает std::thread::join(), а другой поток одновременно вызывает std::thread::joinable() на том же объекте, у вас есть гонка данных и неопределенное поведение.

Вы можете исправить это, используя мьютексы для сериализации вызовов, чтобы только один объект обращался к потоку в любой момент времени, но вместо этого я бы подумал, имеет ли смысл ваш дизайн. Подсказка: нет. Вызов joinable() расскажет вам, есть ли нить с , если не начат звонок в join(). Нить не может быть соединена, пока она все еще работает (вызов join() заблокирует и дождитесь окончания). Таким образом, работающий поток никогда не может видеть joinable() == false для объекта std::thread, который управляет им, потому что, если он может позвонить joinable(), он все еще работает, и поэтому он может быть подключен!

Итак:

  1. Попытка сделать это риски неопределенное поведение, если вы не очень осторожны.

  2. В любом случае это не имеет смысла.

Вместо использовать что-то вроде std::atomic<bool> (или bool и std::mutex), который записывает ли нить было предложено остановить работу и проверить его от ходовой резьбы.