Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Литература / photon_old.doc
Скачиваний:
40
Добавлен:
02.04.2015
Размер:
7.88 Mб
Скачать
      1. Запирание библиотеки Photon'а

Вы можете использовать несколько потоков, устраивая Вашу программу таким образом, чтобы только поток, вызвавший функцию PtInit(), вызывал функции Photon'а, но Вы можете найти подобный подход слишком ограниченным. Библиотека Photon'а является по большей части однопотоковой, но имеет механизм, позволяющий безопасно использовать множество потоков. Этим механизмом является библиотечный замок, предоставляемый функциями PtEnter() и PtLeave(). Этот замок похож на большой взаимоисключающий семафор (мутекс), защищающий библиотеку Photon'а; только один поток может владеть замком в данный момент времени, и только этому потоку позволено выполнять вызовы библиотечных функций Photon'а. Любой другой поток, желающий выполнить вызов функции Photon'а, должен прежде выполнить вызов функции PtEnter(), которая блокирует его до тех пор, пока замок не станет доступным. Когда потоку больше не нужен замок, он вызывает функцию PtLeave(), чтобы позволить использовать библиотеку Photon'а другим потокам.

Чтобы написать Ваши не-Photon'овские потоки:

  • Поставьте вызовы функций PtEnter() и PtLeave() вокруг каких-либо вызовов Photon'овских функций в этих потоках.

  • Сгруппируйте вместе весь Photon'овский код, который сможете, и заключите его в одну пару вход/выход, поскольку это минимизирует количество потенциально сблокированных вызовов PtEnter() в Вашем коде.

  • Попытайтесь убрать весь не-Photon'овский код, который может забирать время для своего исполнения, из Вашей секции вход/выход – в противном случае он может безо всяких на то оснований препятствовать другим потокам в выполнении их работы.

 Не вызывайте функцию PtLeave(), если Ваш поток не вызывал PtEnter(), или Ваше приложение может неправильно себя вести либо приведёт к аварии. Помните, что если Вы находитесь в функции ответной реакции, что-то должно вызвать PtEnter(), чтобы позволить Вам попасть туда.

Функция PtLeave() не передаёт автоматически библиотечный замок другому потоку, блокированному внутри PtEnter(); другой поток становится разблокированным, но затем он должен конкурировать со всеми другими потоками, как если бы он просто вызвал PtEnter(). Вы должны использовать функции PtEnter() и PtLeave() вместо своего собственного мутекса, потому что когда функция PtProcessEvent() (которую вызывает функция PtMainLoop() ) ожидает события, она отпирает библиотеку. Как только PtProcessEvent() получает некое событие, которое она может обработать, она вновь запирает библиотеку. Таким образом, Ваши не-Photon'овские потоки могут свободно получить доступ к функциям Photon'а, когда у Вас нет никаких событий для обработки.

Если Вы используете свой собственный мутекс, о котором PtProcessEvent() не знает, он отопрётся только тогда, когда его отопрёт Ваш код. Это означает, что только то время, когда Ваши не-Photon'овские потоки могут запереть мутекс, является временем, когда Ваше приложение обрабатывает событие, которое вызвало одну из Ваших ответных реакций. Не-Photon'овские потоки не могут запирать мутекс, когда приложение находится в состоянии ожидания.

Соседние файлы в папке Литература