| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Для новичков > Потоки |
| Автор: DareL 9.3.2009, 13:14 | ||
| Посоветуйте, пожалуйста. Прохожу WinApi. Дали следующее заданик:
Где и как тут можно использовать потоки? |
| Автор: Lazin 9.3.2009, 13:39 |
| делишь массив на N частей, первую часть заполняешь из первого потока, вторую из второго и тд... |
| Автор: ilyuha 9.3.2009, 13:44 |
| а что конкретно не понятно, какие подзадачи выделять в отдельные потоки, или, непосредственно, сама реализация? |
| Автор: DareL 9.3.2009, 14:15 | ||
Какие подзадачи выделить. С реализацией я, надеюсь, разберусь |
| Автор: zim22 9.3.2009, 14:57 |
| потоки можно использовать на этапе сортировки. первый поток один кусок массива сортирует, второй - другой. |
| Автор: Artemon 10.3.2009, 13:29 |
| Просто сделай в потоке генерацию случайных числел, а в главном потоке выводи их на форму. Вот тебе и 2 потока. Подсказка: Межпоточное взаимодействие сделай через WM_COPYDATA |
| Автор: GoldFinch 10.3.2009, 14:10 |
зачем такой изврат %) подойдет обычная глобальная структура типа массива вся выборка сгенерится быстрее чем сработает WM_COPYDATA |
| Автор: Artemon 10.3.2009, 17:16 |
| Если мы используем глобальные объекты для потоков, то необходима синхронизация. Отсюда следует что топикстартеру нужно разобираться с межпроцессным взаимодействием, а я думаю это больший геморой, чем использовать WM_COPYDATA в данном случае. |
| Автор: Lazin 10.3.2009, 18:07 | ||
не обязательно если к примеру нужно просто заполнить массив случайными числами, то 1. определяем число процессоров - cpu_count 2. делим массив на cpu_count частей 3. создаем cpu_count потоков, в качестве параметра, передаем в каждый поток начальный и конечный индексы массива, в которые поток должен записывать данные, а так-же указатель на сам массив( либо пару указателей) 4. ждем завершения потоков 5. получаем прирост производительности cpu_count*100% - x Quick sort и merge sort то-же неплохо можно распараллелить... |
| Автор: GoldFinch 10.3.2009, 19:26 |
каким еще межпроцессным? там потоки а не процессы |
| Автор: Artemon 11.3.2009, 07:13 | ||
Lazin, твой способ подойдет только для случая, когда мы один раз заполним массив и закончим потоки, НЕ выводя циклически данные в основной поток. Иначе нам всеравно придется использовать синхронизацию.
Конечноже межпоточным, опечатался. |
| Автор: GoldFinch 11.3.2009, 09:08 |
| Artemon, синхронизация осуществляется оборачиванием кода в критические секции, это куда как проще и прозрачнее чем посылать сообщения и где вообще сказано что в программе должно быть окно? |
| Автор: Lazin 11.3.2009, 09:39 | ||||
основной поток запускает потоки и ждет пока они отработают, после чего может дальше работать, зачем здесь синхронизация?
|
| Автор: C/L 11.3.2009, 10:27 |
наверно это и есть синхронизация, только посредством tasks.join_all(). |
| Автор: Lazin 11.3.2009, 10:35 | ||
рабочие потоки в данном случае синхронизировать ну нужно, только основной поток |
| Автор: Artemon 11.3.2009, 11:54 | ||||||
Об этом и речь Да в вашем примере синфхронизация не нужна, но как вы поступите, если нам постоянно потребуется вести расчет в потоках и постоянно выводить результаты, это я к тому, что не возможно этот сделать без синхронизации.
Это субъективное мнение.
Про окно значит не сказано, а boost значит впорядке вещей получается ? |
| Автор: mrbrooks 11.3.2009, 12:07 | ||
у Lazina - да. Я к этому уже привык. |
| Автор: Lazin 11.3.2009, 12:25 | ||
речь идет об одном конкретном примере, если будет что-то другое, то будет и другое решение. В данном случае, пока потоки не отработают, с массивом нельзя работать и никакие расчеты невозможны. Если, к примеру, нам нужно отсортировать полученный массив, нам придется ждать генерации всех элементов массива, затем начинать сортировку. Можно вместо сортировки вставлять элементы в бинарное дерево поиска, например std::set, тогда сортировать не нужно, но тогда нужно будет синхронизировать доступ к этому дереву. Добавлено через 1 минуту и 4 секунды в любом случае, обмен сообщениями между потоками - не самый эффективный механизм, особенно когда объем обрабатываемых совместно данных велик Добавлено через 3 минуты и 35 секунд кстати, для того что-бы использовать WM_COPYDATA нужно создавать окно, послать такое сообщение потоку нельзя вместо этого, я бы завел очередь, в одном потоке добавлял в нее данные, а из другого читал, ну и естественно оповещал бы поток - потребитель о приходе новых данных с помощью события... |
| Автор: Artemon 11.3.2009, 12:43 |
| Да, большой объем прогонять через WM_COPYDATA не эффективно. Но еслиже у нас маленькое приложение и объем данных мизерный, то моему лучше сделать чрез WM_COPYDATA. Просьба не начинать спор с начала, думаю что все остались при своих мнениях. |
| Автор: GoldFinch 11.3.2009, 13:00 |
| Artemon, какие тогда преимущества дает многопоточность, если юзать WM_COPYDATA? |
| Автор: Lazin 11.3.2009, 13:20 |
| естественно никакие, так-как это сообщение можно послать только с помощь ф-ии SendMessage, которая работает синхронно... если и посылать сообщения потокам, то только через PostThreadMessage |
| Автор: mrbrooks 11.3.2009, 14:00 |
| На самом деле тему раздули - молодцы. Не проще ли автору посоветовать почитать Рихтера главу про потоки и их синхронизацию? На мой взгляд все достаточно доступно и доходчиво. |
| Автор: Artemon 11.3.2009, 14:12 | ||
| 1. Если мы пишем для Windows, используя к примеру WinApi, у нас уже и так есть оконная процедура и с минимальными усилиями мы можем добавить обработку собщения WM_COPYDATA. 2. Если нам необходимо вывести данные из второстепенных потоков в окно.
И что с того, что можно послать только через SendMessage ? Если нужно работать с GUI, это очень даже приемлимый способ. У меня создалось впечатление, что вы думаете мое предложение - использовать взаимодействие через WM_COPYDATA между второстепенными потоками, нет это не так. Я передлагаю использовать WM_COPYDATA только для взаимодействия второстепенного и главного потоков для дальнейшего вывода информации в GUI. |
| Автор: GoldFinch 11.3.2009, 14:21 |
| Artemon, кроме GUI прог в винде есть еще и консольные проги, а еще есть проги без окна и без консоли |
| Автор: Artemon 11.3.2009, 14:34 |
| Неужели? А еще есть драйвера, работающие в нулевом кольце. Которые тоже могут использовать потоки. Только я не пойму вообще к чему это ты сказал. |
| Автор: Lazin 11.3.2009, 14:50 | ||
вообще-то, даже в GUI приложениях в основном потоки используют общие данные и синхронизируют их с помощью различных примитивов синхронизации, и ооочень редко используется WM_COPYDATA WM_COPYDATA обычно используют для организации взаимодействия процессов, тогда, когда оно должно-быть синхронным. |
| Автор: Artemon 11.3.2009, 14:58 |
| Вот ты мне объясни, зачем мне нужна синхронизация, если я один раз из потока в окно хочу одну строку вывести ? Мне очень удобно это сделать через SendMessage + WM_COPYDATA Реальный пример: Программа, которая производит спам рассылку, у которой 4 потока: 1. Сбор IP 2. Проверка IP (является ли этот адрес прокси сервером) 3. Распознавание капчи 4. Основной поток. Все потоки синхронизованы через Mutex-ы И вот например случается событие в потоке проверки IP (№2), о котором мне необходимо информировать пользователя. Я беру и кидаю строку через SendMessage + WM_COPYDATA, в главном окне ловлю его и отображаю в поле статистики. Зачем мне сдалась какая-либо синхронизация, касающаяся вывода сообщений пользователю. //------------------------------------------------------------------------------------------- Про автора топика совсем забыл, у тебя GUI или консольное приложение ? Если GUI, то советую сделать так, как я предложил, если консольное - возьми исходник Лазина. |
| Автор: GoldFinch 11.3.2009, 15:20 |
| Artemon, ты жжошь безусловно формошлепство накладывает некоторый оконный отпечаток на личность) Добавлено через 1 минуту и 2 секунды еще можно отправлять данные на почту по POP3 и читать от туда другим потоком |
| Автор: Lazin 11.3.2009, 15:33 | ||||||||
я хотел предложить записывать данные в файл одним потоком и читать их оттуда другим, но ты меня обошел))
Добавлено через 3 минуты и 24 секунды
с данной программой все просто, ее просто не надо писать
блин, откуда вы все знаете мою фамилию? |
| Автор: Artemon 11.3.2009, 15:41 | ||
| Если вы мне предложите более лаконичное решение примера, который я привел (конечно же обоснованное решение), то я соглашусь с вами, сейчас получается все на уровне разговора без аргументов (особенно GoldFinch) Добавлено через 1 минуту и 54 секунды
Ну ты тоже скажешь, это мой хлеб практически. |
| Автор: GoldFinch 11.3.2009, 15:46 | ||
тут полфорума - экстрасенсы синхронизация через критические секции выглядит так
- лаконичнее некуда - 1 строчка на то чтобы сделать функцию thread-safe неужели WM_COPYDATA в каком-то месте удобнее? |
| Автор: Artemon 11.3.2009, 15:55 |
| Критическая секция - это как говорится хорошо, Покажи мне пример в котором из вторичного потока выводятся данные в Windows окно. Если кто-то покажет более удобный способ сделать то, о чем я говорю, то я с удовольствием буду его использовать, я ведь не враг самому себе |
| Автор: Lazin 11.3.2009, 16:10 | ||
а как-же вечные муки в аду? |
| Автор: Artemon 11.3.2009, 16:32 | ||
| Ну вот ты используешь PostMessage + Сообщение + Mutex И чем оно лучше SendMessage + Сообщение ? Вообще в упор не вижу никаких плюсов. Добавлено через 33 секунды
Все там будем... |
| Автор: Lazin 11.3.2009, 16:39 |
твои проблемы) тем, что в случае SendMessage, поток вызвавший SendMessage будет ждать пока не отработает оконная процедура, а в моем коде этого не будет |
| Автор: Artemon 11.3.2009, 16:55 | ||
Единственное в чем с тобой согласен это:
Но опятьже, я вызываю SendMessage довольно редко и для меня это не критично. |