Всем привет! Возникла такая проблема: пишу програмку на C++ dialog based MFC приложение для копирования файлов. Суть: есть главное окно в котором мы выбираем файл для копирования и место, куда нужно его скопировать. При нажатии на кнопку "копировать", должно открываться малекое окошко, в котором мы можем видеть процес копировани с прогрес баром, кнопками "отмена" и "приостановить/восстановить копирование". Таких окон одновременно может быть много одновременно.
Я уже реализовал процес копирования для одного файла, но только в одном потоке. И на период пока файл копируеться интерфейс замораживаеться. Подскажите пожалуста, примером разработки многопоточных приложений, советом или кто чем может. Спасибо!
Здравствуйте, yozhik89, Вы писали:
Y>Всем привет! Возникла такая проблема: пишу програмку на C++ dialog based MFC приложение для копирования файлов. Суть: есть главное окно в котором мы выбираем файл для копирования и место, куда нужно его скопировать. При нажатии на кнопку "копировать", должно открываться малекое окошко, в котором мы можем видеть процес копировани с прогрес баром, кнопками "отмена" и "приостановить/восстановить копирование". Таких окон одновременно может быть много одновременно.
Y>Я уже реализовал процес копирования для одного файла, но только в одном потоке. И на период пока файл копируеться интерфейс замораживаеться. Подскажите пожалуста, примером разработки многопоточных приложений, советом или кто чем может. Спасибо!
Создай поток, который будет создавать потоки копирования и ждать их окончания, не забывай о синхронизации.
Здравствуйте, yozhik89, Вы писали:
Y>Всем привет! Возникла такая проблема: пишу програмку на C++ dialog based MFC приложение для копирования файлов. Суть: есть главное окно в котором мы выбираем файл для копирования и место, куда нужно его скопировать. При нажатии на кнопку "копировать", должно открываться малекое окошко, в котором мы можем видеть процес копировани с прогрес баром, кнопками "отмена" и "приостановить/восстановить копирование". Таких окон одновременно может быть много одновременно.
Возможностей реализации — вагон.
1. Можешь сделать по одному потоку на каждый копируемый файл. Стартуешь потоки из основного интерфейсного потока, см. _beginthreadex. Окошки создаешь в основном потоке. Чтобы показать процесс копирования из рабочих потоков шлешь уведомления (главному окну приложения или "своему" окошку, с прогресс баром), например, через PostMessage.
Очевидный минус — если в несколько потоков читать файлы с одного диска скорости не прибавляется.
2. Один интерфейсный поток и один рабочий. Использовать асинхронную работу с файлами (см. флаг FILE_FLAG_OVERLAPPED для функции CreateFile). Придется организовать некоторую очередь с "заданиями" (т.е. с файлами, которые надо копировать).
И в п.1, и в п.2 не забывать про синхронизацию.
3. Использовать асинхронный режим работы с файлами и забить на потоки вообще.
4. Без дополнительных потоков, читать файл по частям. После каждого скопированного фрагмента диспатчить оконные сообщения (см. PeekMessage, GetMessage, TranslateMessage, DispatchMessage). Надо учитывать рекурсию — если запустить копирование большого количества файлов, то выход из функции — обрабочика команды не произойдет, пока _все_ файлы не будут скопированы. Способ плохой, но имеет право на существование.
_____________________
С уважением,
Stanislav V. Zudin
Здравствуйте, yozhik89, Вы писали:
Y>Всем привет! Возникла такая проблема: пишу програмку на C++ dialog based MFC приложение для копирования файлов. Суть: есть главное окно в котором мы выбираем файл для копирования и место, куда нужно его скопировать. При нажатии на кнопку "копировать", должно открываться малекое окошко, в котором мы можем видеть процес копировани с прогрес баром, кнопками "отмена" и "приостановить/восстановить копирование". Таких окон одновременно может быть много одновременно.
Y>Я уже реализовал процес копирования для одного файла, но только в одном потоке. И на период пока файл копируеться интерфейс замораживаеться. Подскажите пожалуста, примером разработки многопоточных приложений, советом или кто чем может. Спасибо!
Создаёшь рабочий поток, который ждёт на GetQueuedCompletionStatus(). Этот поток управляет всеми операциями копирования — выдаёт запросы чтение/запись, и управляет дескрипторами, связанными с операциями.
Основной GUI поток посылает команды (начать/прервать копирование) через PostQueuedCompletionStatus().
Рабочий поток посылает уведомления (прогресс операций) основному потоку через PostMessage().
Потока будет всего 2. Никакого явного разделения данных и мьютексов. Всё общение между потоками через сообщения.
Здравствуйте, Stanislav V. Zudin, Вы писали:
SVZ>2. Один интерфейсный поток и один рабочий. Использовать асинхронную работу с файлами (см. флаг FILE_FLAG_OVERLAPPED для функции CreateFile). Придется организовать некоторую очередь с "заданиями" (т.е. с файлами, которые надо копировать).
Развивая п.2:
В рабочем потоке использовать синхронный режим чтения файла, читать файлы по одному. По скорости, думаю, будет не хуже п.2.
_____________________
С уважением,
Stanislav V. Zudin
"in the case of high data rates" использование IOCP тоже "wrong". Во-первых, GQCS и PQCS это всегда переход в ядро, что сильно медленно, во-вторых эти очереди используют non-paged память ядра, что может вызывать серьёзные проблемы.
В целом, использование IOCP для произвольного производительного и надёжного месседжинга — это не очень хороший путь.