2015-02-13 2 views
0

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

Мы используем C++ 11 для нашего проекта, и это выход в нашем компьютере:

............ успеха! Тестирование завершено. Проведено 12 тестов. 12 удалось.

Но когда мы пытаемся запустить на ARM, как вы можете увидеть здесь: https://travis-ci.org/OpenStratos/server/builds/49297710

Он говорит следующее:

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

После некоторой отладки, я понял, что этот вопрос приходит в этот код: https://github.com/OpenStratos/server/blob/feature/temperature/serial/Serial.cpp#L91

this->open = false; 
while(! this->stopped); 

И есть другой поток делает противоположное:

while(this->open) 
{ 
    // Do stuff 
} 
this->stopped = true; 

Первый код называется когда мне нужно остановить поток, а двойной флаг используется для того, чтобы поток мог обновлять текущий объект, даже если он останавливается. Обе переменные имеют тип std :: atomic_bool, но кажется, что в while (! this->stopped); он не проверяет его, и он предполагает while (true);.

В этом случае? как это можно решить? почему он работает по-другому на моем процессоре x86_64, чем на ARM?

Заранее спасибо.

+0

Какой компилятор? Какие параметры командной строки? –

+0

Варианты компилятора и stdlib на системах? Кроме того, вы можете попробовать использовать методы загрузки/хранения, которые позволяют передавать детали заказа. –

+0

Почему вы не используете обычные механизмы синхронизации потоков? 'while (! this-> stop);' это плохой способ сделать это. –

ответ

0

Наконец, проблема заключалась в том, что среда, которую я создавала в Travis.ci, работала неправильно. В реальном оборудовании ARM работает правильно.

1

Основная гарантия, сделанная std::atomic<T>, состоит в том, что вы всегда можете прочитать a значение. Согласованность не обязательно гарантируется.

Теперь, в этом случае вы полагаетесь на .operator bool что эквивалентно .load(memory_order_seq_cst) и operator=(x), который .store(x, memory_order_seq_cst). Это должно обеспечить последовательный последовательный порядок памяти.

Заказ, который вы наблюдаете на ARM, выглядит последовательно согласованным со мной. Быстрый, что вы не еще смотри stopped == true в порядке. На этом нет ограничений по времени. Компилятор не может поменять операцию памяти другой операцией памяти, но может зависеть от нее.

Главный вопрос, почему эта нить должна быть остановлена ​​вообще. Если бы была какая-то реальная, наблюдаемая работа в теле цикла этого потока, это тело цикла не могло быть переупорядочено относительно проверки stopped==true.

+0

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

Смежные вопросы