Модель, Представление, Контроллер - Я понимаю диаграмму классов, но я не понимаю все проблемы потоков Совет? - PullRequest
1 голос
/ 12 октября 2010

Я недавно прочитал книгу Head First Design Patterns , и мне особенно понравилось, как глава о MVC, казалось, свела все вместе из предыдущих глав. Однако сейчас я нахожусь на грани реализации шаблона MVC (используя wxWidgets в C ++), и я начинаю понимать, что я не так сильно понимаю проблемы с многопоточностью.

У меня есть представление, которое должно постоянно обновляться при изменении модели, однако пользователь может взаимодействовать с элементом управления и также влиять на модель. Поскольку View / Control и Модель будут работать в 2 разных потоках (или это 3?), Как я могу убедиться, что у меня нет двух потоков, пишущих в один и тот же объект данных? Я несу ответственность за настройку блокировки общих данных? Или я просто каким-то образом гарантирую, что у меня не будет никаких проблем, если я правильно использую фреймворк событий?

Ответы [ 2 ]

4 голосов
/ 12 октября 2010

MVC изначально был придуман для систем, основанных на сообщениях (Smalltalk), что в некотором смысле противоположно многопоточности.

Лучший (теоретический) способ, которым я знаю, как жениться на MVC, и многопоточность - это концепция активного объекта (или субъекта): объект живет в своих собственных потоках, может отправлять / получать сообщения / события другим активным объектам. Это предполагает, что все действия над объектом синхронизированы - поскольку отдельные объекты связаны с одним потоком - что является аналогом мьютекса для каждого объекта.

У меня есть представление, которое должно постоянно обновляться при изменении модели, однако пользователь может взаимодействовать с элементом управления и также влиять на модель. Поскольку View / Control и Модель будут работать в 2 разных потоках (или это 3?),

У меня нет опыта работы с wxWidgets, но обычно GUI-часть приложения является однопоточной (, очевидно, подходит и для wxWidgets ), работает исключительно в основном потоке.

Вид и Контроллер связаны с пользовательским интерфейсом, поэтому должны выполняться в основном потоке. С дополнительной нитью для модели, которая делает его 2.

как мне убедиться, что у меня нет двух потоков, пишущих в один и тот же объект данных?

Мьютекс для каждого объекта.

Я несу ответственность за установку блокировок для общих данных?

Да.

Или я просто каким-то образом гарантирую, что у меня не возникнет проблем, если я правильно использую фреймворк событий?

Нет. Как упоминалось выше, GUI является однопоточным. Если вы запускаете собственные потоки, то вам нужно позаботиться о синхронизации.

Если из основного потока / потока GUI вы запускаете действие в другом потоке, то, очевидно, вам нужно синхронизировать доступ к общим данным. Если другой поток хочет получить доступ к GUI, то вы должны использовать специальные функции (упомянутые в связанной статье) для запуска событий в основном потоке GUI (например, модель была обновлена ​​в фоновых потоках, View должен перерисовать ее в основном потоке).

Если фоновый поток постоянно обновляет модель, то, очевидно, нужно быть особенно внимательным, чтобы поток не держал мьютекс все время заблокированным, чтобы основной поток, GUI, в котором работает View, также мог получить доступ к модели. (Требуется какая-то блокировка чтения-записи .) Контроллер должен быть отключен, поскольку, если приложение делает что-то в фоновом режиме, взаимодействие с пользователем может быть нежелательным.

В целом, я думаю, что лучше держать MVC в главном потоке. Поток графического интерфейса не генерирует значительную нагрузку на процессор, и часто для простоя имитируют фоновые задания ( у wx их тоже ).

0 голосов
/ 12 октября 2010

Теоретически вы можете запустить MVC в одном потоке, но в целом да, вы должны иметь блокировки в соответствующих местах.

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

...