Нереентерабельная функция в API, используемом в многопоточной программе.

Я использую QT API в C++, но я полагаю, что ответы могут быть эффективно получены от людей, не имеющих опыта работы с QT.

QT имеет функцию в своем классе обработки XML, называемую setContent(), которая определена как нереентерабельная. При вызове setContent() считывает файл XML в память и возвращает его в виде структуры данных.

Насколько я понимаю, нереентерабельная функция — это функция, которую небезопасно вызывать одновременно из нескольких потоков, даже если функция вызывается для работы с разными файлами/объектами.

Исходя из этого, я понимаю, что я не смогу иметь более одного потока, открывающего XML-файлы с помощью этой функции, если только оба этих потока каким-то образом не защищены от одновременного доступа к функции setContent().

Это правильно? Если это так, то это кажется действительно плохим способом написания API, поскольку это вообще не похоже на функцию, которая интуитивно может вызвать проблемы с многопоточностью. Кроме того, API вообще не предоставляет мьютекс.

Итак, чтобы использовать эту функцию в моей многопоточной программе, где несколько потоков будут открывать разные XML-файлы, как лучше всего организовать доступ к функции setContent()? Должен ли я создавать внешний мьютекс в отдельном заголовочном файле, который включается в каждый файл, который будет обращаться к XML?


person Nantucket    schedule 30.08.2011    source источник


Ответы (2)


Похоже, все дело в static QDomImplementation::InvalidDataPolicy invalidDataPolicy. Это единственные статические данные, которые используют классы QDom***.

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

Я предполагаю, что если ваша программа никогда не вызывает setInvalidDataPolicy(), вы можете безопасно анализировать XML из разных потоков.

person hamstergene    schedule 30.08.2011

Исходя из этого, я понимаю, что я не смогу иметь более одного потока, открывающего XML-файлы с помощью этой функции, если только оба этих потока каким-то образом не защищены от одновременного доступа к функции setContent().

Я думаю, ты прав.

Итак, чтобы использовать эту функцию в моей многопоточной программе, где несколько потоков будут открывать разные XML-файлы, как лучше всего организовать доступ к функции setContent()? Должен ли я создавать внешний мьютекс в отдельном заголовочном файле, который включается в каждый файл, который будет обращаться к XML?

Опять же, я склонен согласиться с вами в отношении мьютекса. (Кстати, Qt предоставляет QMutex). вы имеете в виду внешний мьютекс в заголовочном файле, поэтому я просто создам ровно один мьютекс и отправлю указатель на этот мьютекс всем потокам, которые в нем нуждаются.

person B. Decoster    schedule 30.08.2011