Как одновременно загрузить и преобразовать двоичный файл, используя потоки? - PullRequest
4 голосов
/ 22 июня 2010

У меня есть программа, которая загружает двоичный файл с другого компьютера.
У меня также есть другая отдельная программа, которая может преобразовать этот двоичный файл в читаемый человеком файл CSV.

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

Я считаю, что могу успешно запустить другую ветку, но как мне синхронизировать цепочку конвертации с основной загрузкой?

т. Е. Преобразование совпадает с загрузкой, необходимо дождаться загрузки еще, затем начать преобразование снова и т. Д.

Это похоже на Синхронное выполнение нескольких потоков ?Если это так, значит ли это, что загруженный двоичный файл должен быть ресурсом, к которому обращаются семафоры?

Нахожусь ли я на правильном пути или мне нужно указать в другом направлении, прежде чем я начну?

Любой совет приветствуется.

Спасибо.

Ответы [ 3 ]

3 голосов
/ 22 июня 2010

Это классический случай проблемы производитель-потребитель с download thread в качестве producer и conversion thread в качестве consumer.

Google вокруг, и вы найдете реализацию для вашего языка по вашему выбору. Вот некоторые из MSDN: Как: реализовать различные шаблоны «производитель-потребитель» .

2 голосов
/ 22 июня 2010

Да, вам, несомненно, нужны семафоры (или что-то подобное, например, событие или критическая секция) для защиты доступа к данным.

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

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

По крайней мере, по моему опыту, этот тип дизайна устраняет большой процент проблем синхронизации потоков.

Редактировать: я не уверен насчет рекомендаций о том, как проектировать потокобезопасную очередь, но я разместил код для простого в предыдущем ответе .

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

2 голосов
/ 22 июня 2010

Вместо загрузки в файл, вы должны записать загруженные данные в канал.Поток преобразования может считывать данные из канала и затем записывать преобразованный вывод в файл.Это автоматически синхронизирует их.

Если вам нужен как исходный файл, так и преобразованный, просто попросите поток загрузки записать данные в файл, а затем записать те же данные в канал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...