У меня есть многопоточная программа, которая при запуске через strace
показывает это:
read(10, "lorem ipsum...", 100) = 100
read(10, 0x2ae9ebcb5000, 8191) = ? ERESTARTSYS (To be restarted)
--- SIGTERM ... ---
Всякий раз, когда возникает ошибка ERESTARTSYS, программа зависает при чтении. Когда ERESTARTSYS не происходит, программа успешно завершается, и я получаю:
read(10, "lorem ipsum...", 100) = 100
read(10, "", 8191) = 0
...
exit_group(0)
Глядя на strace
справочную страницу (для strace, который не моя версия) и ТАК вопросы, как this и это, кажется, что чтение прерывается некоторыми сигнал. Я мог неправильно понять документ, но я не вижу никакого сигнала, кроме SIGTERM, который, как я предполагаю, исходит от моего выхода из программы.
Я определил, что два чтения происходят из вызова std::getline, который читается дважды, когда разделитель не найден (он не найден, потому что разделитель неверен и нигде в строке, но я не могу исправить это, потому что это находится в библиотеке, которую я не могу контролировать). Добавление разделителя в строку, по-видимому, предотвращает второе чтение, что приводит к тому, что код выполняется без проблем.
Я также уверен, что в коде есть какое-то состояние гонки, потому что, когда я отключаю параллелизм, эта ошибка не возникает. Одно из моих диких предположений заключается в том, что чтение прерывается во время переключения контекста потока, однако это всего лишь дикое предположение, и ничто в strace не указывает на то, что это правда. Кроме того, я не уверен, почему он просто не перезапустится после обратного включения. Однако я не могу найти условие гонки и надеялся, что понимание strace и ERESTARTSYS поможет мне понять, где ошибка. является.
Если это поможет, я использую RHEL5 и компилирую с помощью gcc 4.7.2.
ERESTARTSYS
предполагается использовать только в ядре для прозрачной обработки. Ваше приложение не должно его видеть. - person tangrs   schedule 10.08.2014