#multithreading #dialog #controls #mutex
#многопоточность #диалоговое окно #элементы управления #мьютекс
Вопрос:
У меня есть диалоговое окно с некоторыми элементами управления флажками.
Это диалоговое окно может создать рабочий поток, который может получить доступ к некоторым из этих элементов управления во время его выполнения.
Но пользователь также может изменять эти элементы управления флажками во время выполнения рабочего потока.
Хотя это маловероятно, может случиться, что поток попытается прочитать некоторые из этих элементов в тот самый момент, когда пользователь захочет их изменить.
Как я могу защитить элемент диалогового окна от одновременного доступа между основным потоком и рабочим потоком?
Я полагаю, мне следует создать мьютекс, и этот мьютекс легко использовать из рабочего потока, но я не вижу, где я мог бы вставить код для блокировки элемента диалогового окна с тем же мьютексом, когда пользователь захочет его изменить.
Есть ли кто-нибудь, кто мог бы мне помочь с этим?
Заранее спасибо.
Gingko
Ответ №1:
Вы не указали, какую платформу используете, поэтому я собираюсь предположить, что независимо от платформы, она следует общим правилам, согласно которым только поток пользовательского интерфейса может получать доступ к элементам управления пользовательского интерфейса. Из этого правила следует очевидное следствие, что другие потоки не могут напрямую считывать состояние флажка.
Решение заключается в следующем:
- Создайте несколько закрытых логических полей, соответствующих флажкам в объекте, представляющем диалоговое окно.
- Всякий раз, когда пользователь изменяет флажок, обновляйте соответствующее логическое поле.
- Предоставьте эти поля как свойства, доступные только для чтения, для чтения другими потоками.
- (необязательно) Защитите весь доступ к логическим полям с помощью мьютекса.
Пункт 4 необязателен, потому что я знаю, что на всех архитектурах нет опасности разрыва при доступе к логическому полю.
Весь смысл этого заключается в том, чтобы избежать проблемы, связанной с тем, что чтение и запись состояния управления пользовательского интерфейса не являются потокобезопасными. Но в общем дизайне, который вы описываете, вы никогда не будете свободны от гонки данных. Когда ваш рабочий поток считывает состояние, пользователь, возможно, только что изменил его или собирается изменить. Вы не можете знать, и как только вы разрешаете рабочему потоку работать параллельно с потоком пользовательского интерфейса, вы должны принять этот факт.
Комментарии:
1. Извините, я работаю на Windows (любых последних версиях), используя Visual Studio. На самом деле, я ожидал поделиться элементами диалогового окна напрямую, потому что, хотя сейчас мне нужен доступ к элементу флажка, возможно, позже мне понадобится доступ к более сложным элементам (например, к спискам, к которым оба потока могут захотеть получить доступ). Gingko
2. @Gingko Вам разрешено взаимодействовать только с оконными элементами управления (т. Е. с чем угодно с
HWND
) в потоке, с которым связан этот HWND. Это поток, в котором был вызван CreateWindow. Почти всегда это основной поток вашего приложения. Вы не можете получить доступ к оконным элементам напрямую из разных потоков.