2015-12-22 2 views
2

В разных библиотеках некоторые операции должны выполняться в том же потоке, в котором произошла другая операция. Некоторые примеры включают Swing EDT и OpenGL.Почему необходимо использовать одну и ту же резьбу?

Так что, когда что-то говорит что-то вроде «Вы должны вызывать только methodX() в том же потоке, который создал ObjectY» или «Контекст должен сначала быть связан с ThreadX перед вызовом Мефодий» ...

Что происходит под капотом?

Как это соблюдается?

Почему это делается? например Почему я не могу отправить команду из другого потока, даже если объект подвергается какой-либо операции?

+1

Я предполагаю, что идентификатор потока хранится где-то и сравнивается с текущим исполняемым идентификатором потока. Если он не соответствует ему, генерирует исключение, код, который имеет это, вероятно, не предназначен для потокобезопасности, поэтому они просто безопасно прерывают вашу программу, прежде чем что-либо произойдет хуже. – Neijwiert

+0

Я полагаю, это разумно. Я лично не поклонник принудительной безопасности, но в конце концов это не проблема. Если вы хотите ответить на этот вопрос, я соглашусь с ним. –

+0

Я не чувствую, что это правильно ответило, я думаю, что кто-то, у кого больше опыта в этом деле, должен ответить на него. – Neijwiert

ответ

1

Большинство оконных систем имеют довольно специфические правила взаимодействия между потоками и кодом, который (непосредственно) управляет окном. Для большинства типичных случаев это обрабатывается достаточно прозрачно из-за того, что «внешний мир» отправляет сообщения, а код, который обрабатывает эти сообщения, и непосредственно манипулирует целевым окном, выполняется в (одном) правильном потоке.

Я бы предположил, что мы видим проявление тех же ограничений здесь. Разница заключается в том, что OpenGL и Swing EDT отображают функциональность с точки зрения вызовов функций вместо отправляемых сообщений. Эти функции непосредственно манипулируют базовым окном способами, которые типичная система окон требует только из правильной нити, поэтому вы должны только вызывать эти функции из правильной нити.

Что касается принудительного исполнения: по крайней мере, в большинстве систем, которые я видел, «принудительное исполнение» состоит из вашего приложения, когда вы делаете неправильную вещь. Если вам повезет, вы можете получить приятное и полезное сообщение от ОС, в котором говорится, что вы вызвали функцию X из неправильного потока (хотя функция X, к которой она относится, вполне может быть тем, который вы никогда не вызывали напрямую, из любого потока). В более общем случае вы получите ошибку, например, segmentation fault attempting to write address 0x12345678, без указания того, что вы сделали неправильно, чтобы вызвать это вообще.

Что касается того, почему это сделано: как отмечено выше, это более или менее подкреплено базовыми системами окон. Если вы хотите сделать еще один шаг и спросить, почему они это задают, я бы предположил, что это прежде всего вопрос простоты и скорости. Требование о том, чтобы все прямые взаимодействия с окном проходили через один поток, избегает использования параллелизма повсюду. Добавление всех мьютексов (и таких), необходимых для одновременного взаимодействия нескольких потоков с ним, приведет к значительно более медленной разработке и (возможно) еще более медленному выполнению.

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