Как получить доступ к переменной потока, используя OmniThreadLibrary? - PullRequest
3 голосов
/ 11 января 2011

Это кажется простой задачей, я просто не знаю, как начать использовать OmniThreadLibrary:

Я создаю задачу, которая выполняет некоторую обработку в фоновом режиме.Результаты хранятся в полях класса задач и постоянно заполняются новыми значениями.

Теперь основной поток хочет читать эти поля и время от времени отображать их значения.
Поэтому ему необходим доступэти поля и убедитесь, что они не записаны в эти моменты (Синхронизировать).

Как это можно сделать с OmniThreadLibrary?

Ответы [ 2 ]

3 голосов
/ 11 января 2011

В OTL нет прямой поддержки совместного использования данных владельцем / потоком, потому что весь мой многопоточный опыт говорит мне, что это всегда плохо.(Согласитесь, иногда это единственное решение, но все-таки это плохо.)

Вам следует пойти по второму предложению mghie - создать (необязательно основанный на интерфейсе) объект и передать этот объект (или его интерфейс)в тему.Примерно так:

sharedData := TSharedData.Create;
task := CreateTask(worker).SetParameter('shared', sharedData).Run;

работник:

sharedData := Task.Param['shared'].AsObject as TSharedData;

Другой способ решения этой проблемы - отправка сообщения «Пожалуйста, отправьте обновление» задаче всякий раз, когда пользователь нажимает UpdateNow.кнопка.Затем эта задача отвечает объектом, содержащим текущее состояние.Однако, если задача выполняет длительные непрерывные вычисления, это решение не является действительно подходящим, и подход с общим состоянием работает лучше.

2 голосов
/ 11 января 2011

Ознакомьтесь с тестом OTL 23, в котором реализован поиск в фоновом режиме. Метод SetParameter() используется для установки свойств поиска, канал Comm используется для передачи результатов обратно в основной поток. Связь уже поточнобезопасна, вам не нужно реализовывать дальнейшую синхронизацию.

Edit:

Если вам нужна не push-модель, а pull-модель, вы, конечно, можете использовать стандартные инструменты синхронизации: объект, имеющий критическую секцию, которая используется во всех средствах доступа для защиты данных от одновременного доступа. Этот объект может быть самим объектом задачи или любым третьим объектом, который создается потоком GUI и передается в задачу путем (снова) вызова SetParameter(). Если вы используете не объект, а указатель интерфейса, вы получите большую безопасность, поскольку порядок уничтожения больше не важен, объект, содержащий данные, будет уничтожен только после сброса последней ссылки на реализуемый интерфейс.

...