Передача структур данных к различным потокам

У меня есть приложение, которое будет порождать несколько потоков. Однако я чувствую, что могла бы быть проблема с потоками, получающими доступ к данным, которыми они не должны быть.

Вот структура потокового приложения (извините для грубости):

                   MainThread
                  /          \
                 /            \
                /              \
        Thread A               Thread B
       /        \              /       \
      /          \            /         \
     /            \          /           \
Thread A_1     Thread A_2   Thread B_1    Thread B_2

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

Так, datastructure создается в MainThread, будет изменен в начитанном потоке (Распараллельте A, и т.д.), характерный для того потока и затем членской переменной, от которой datastructure отправляется в потоки Letter_Numbered.

В настоящее время начитанный класс потока имеет членскую переменную и когда класс создается, datastructure от mainthread передается в ссылкой, вызывая конструктора копии, таким образом, начитанный поток имеет свою собственную копию для проигрывания с.

Поток lettered_numbered просто берет в строковой переменной от структуры данных в начитанном потоке. Мой вопрос, действительно ли это приемлемо? Существует ли намного лучший способ гарантировать, что каждый начитанный поток заставляет свою собственную структуру данных играть с?

Извините за несколько плохое объяснение оставьте комментарии, и я попытаюсь разъясниться.

Править: Таким образом, мой начитанный конструктор потока должен принять ЗНАЧЕНИЕ структуры данных, не ссылка?

6
задан Flimzy 13 June 2018 в 23:35
поделиться

5 ответов

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

РЕДАКТИРОВАТЬ: Удален комментарий о строках. По какой-то причине я предполагал .NET.

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

5
ответ дан 10 December 2019 в 02:43
поделиться

Вы видимо делаете копию данных для каждого трэда и все работает? тогда нет проблем.

Вот несколько дополнительных мыслей:

  • Если данные доступны только для чтения, вы можете совместно использовать одну структуру, и все будет в порядке, если каждое чтение будет небольшим и быстрым (базовые типы)
  • Если данные необходимо быть записанными, но «закрытыми» (или содержащимися) для каждого потока, а затем отправить копию в каждый поток (что вы делаете). Предостережение: я предполагаю, что данные не слишком велики, а копия не потребляет много ресурсов.
  • Если необходимо записать данные и разделить новые значения между потоками, тогда вам нужно подумать об этом (прочитать) и создать правильный дизайн. Мне нравится объект транзакции для централизации каждой операции чтения / записи потоков. Как крошечная база данных в памяти. Проверьте мьютекс потока, семафоры и критические секции). Имея дело с огромным набором данных, я использовал базу данных для централизации запросов (см. ODBM). Вы также можете проверить существующие библиотеки очередей обмена сообщениями (например, MSMQ), чтобы упорядочить и синхронизировать изменение данных.

Надеюсь, это поможет.

1
ответ дан 10 December 2019 в 02:43
поделиться

Существует паттерн, называемый Active Object Pattern , в котором каждый объект выполняется в собственном потоке. Такие фреймворки как ACE поддерживают это. Если у вас есть доступ к таким фреймворкам, используйте их. В любом случае, я считаю, что создать новый экземпляр объекта и позволить ему выполняться в собственном потоке гораздо проще, чем вызывать copy-constructor для создания копии объекта. Попробуйте также найти решение, использующее Thread Local Storage.

3
ответ дан 10 December 2019 в 02:43
поделиться

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

-1
ответ дан 10 December 2019 в 02:43
поделиться

Вы смотрели на потоки ускорения ?

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

Это очень похоже на то, как Java реализует потоки, и большую часть времени это имеет смысл с точки зрения дизайна.

1
ответ дан 10 December 2019 в 02:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: