здравствуйте. такие дела:
пытаюсь считать текст из файла пословно и добавить каждое слово в <map>
<map> определил глобально, файл тоже определен глобально.
функция чтения такая:
string str;
while (!mfile.eof()){
mfile >> str;
mymap[str]+=1;
}
return 0;
}
из мейна вызываю 4 потока
AfxBeginThread(reading_th1,NULL);
AfxBeginThread(reading_th1,NULL);
AfxBeginThread(reading_th1,NULL);
AfxBeginThread(reading_th1,NULL);
итог 3 состояния:
работает (при этом снижает общее время выполнения программы на несколько секунд, что и требуется)
зависает
ошибка
причем выскакивают рандомно, как понимаю это результат когда потоки одновременно пытаются прочитать файл.
готов слушать ваши ругательста и угрозы побить по рукам, но дайте ссылки или сами напишите примеры и теорию как это использовать ПРАВИЛЬНО. сегодня первый день пытаюсь сам прикрутить потоки к своей программе. а в учебнике вузовском нету )
4 апреля 2010 в 19:02
HANDLE h=AfxBeginThread(MyFunc,NULL);
WaitForSingleObject(h,INFINITE);
он его не ждет)
3 апреля 2010 в 14:04
Если не ошибаюсь, то в WaitForSingleObject надо передать HANDLE потока, завершения которого надо дождаться.
2 апреля 2010 в 23:04
1. stl не поддерживает многопоточность (точнее ее не поддерживают большинство реализаций)
2. следовательно синхронизацию (на любых примитивах) + _не_использовать итераторы – они инвалидируются для мапы при вставке
2 апреля 2010 в 22:01
спасибо. интересно вас читать. с потоками боле менее хорошо пошло. делаю так как сказал кто то выше, один поток читает файл, другие два прочитанные значения пишут в map
не могу только пока разобраться как ждать завершение потока с помощью WaitForSingleObject
2 апреля 2010 в 16:02
Дмитрий, если Вы не умеете внимательно читать, что написано, то это Ваши проблемы. И не стоит при этом обвинять в других в незнании.
Еще раз повторяю для Вас:
Если известно место вставки очередного элемента, например, если в map добавляются элементы ОТСОРТИРОВАННОГО массива, то время вставки меньше логарифма. STL предоставляет инструмент для этого, функция insert возвращая итератор на вставленный элемент. Времени для вставки следующего элемента будет затрачено меньше логарифма.
2 апреля 2010 в 13:03
для всех тех, кто до сих пор считает, что прав:
даю на вход последовательность, например, чисел, никак не упорядоченных (вместо чисел – строки из файла, как у автора).
Ну, предложитеалгоритм быстрее, чем за логарифм
2 апреля 2010 в 13:00
#18 //cplusplus.com/reference/stl/map/insert/
Раздел Complexity.
2 апреля 2010 в 11:04
Только вот rand() не там )))
2 апреля 2010 в 0:05
#18 //pastie.org/899458
результат:
============================
Data size: 100
InsertSorted: 0 sec.
InsertSimple: 0 sec.
============================
Data size: 1000
InsertSorted: 0 sec.
InsertSimple: 0 sec.
============================
Data size: 10000
InsertSorted: 0 sec.
InsertSimple: 0.01 sec.
============================
Data size: 100000
InsertSorted: 0.01 sec.
InsertSimple: 0.03 sec.
============================
Data size: 1000000
InsertSorted: 0.15 sec.
InsertSimple: 0.42 sec.
============================
Data size: 10000000
InsertSorted: 1.51 sec.
InsertSimple: 6.71 sec.
2 апреля 2010 в 0:02
#18, если вставляется что-то произвольное, то нельзя. А вот если вам заранее что-то известно про вставляемое – к примеру, что массив вставляемых значений отсортирован – то возможно за счет этого выиграть по сравнению с логарифмом.
1 апреля 2010 в 20:04
#17, Учи теорию… нельзя, значит нельзя!И это доказано. И спорить ненадо! место вставки еще узнать надо, сказано выше же!
1 апреля 2010 в 12:03
#16, получится, если заранее известно место вставки , пример приведен в #13.
1 апреля 2010 в 9:03
#12, быстрее, чем за логарифм не получится, т.к. это нижняя оценка, т.е."Большая подкова"(Log(N))
1 апреля 2010 в 7:03
А если требуется сильно ускорить процесс, я бы на вашем месте попробовал две вещи.
Во-первых, можно заменить потоковое чтение на fscanf и посмотреть, как изменится скорость.
Во-вторых, раз вы все равно работаете в MFC, можно воспользоваться CreateFileMapping и MapViewOfFile и работать с файлом из памяти.
1 апреля 2010 в 7:02
Первое. Если я не ошибаюсь, STL не гарантирует вам правильной работы при одновременном использовании (для записи) одного объекта из разных потоков. Потому требуется на каждый поток выделить отдельный map, после чего их объединить необходимым вам способом.
А даже если STL это гарантирует, конструкция mymap[str]+=1; будет вести себя неправильно. Так что тут у вас серьезная проблема.
1 апреля 2010 в 3:04
У map::insert логарифмическая сложность, за исключением случая, когда пользуешься версией insert( iterator, value), и вставляешь отсортированные данные друг за другом (в параметре iterator передаешь итератор из результата предыдущей вставки) – в этом случае сложность O(1).
1 апреля 2010 в 0:01
почему нельзя одним потоком прочитать файл в std::list или даже в std::vector, а уже потом потоками засунуть в std::map?
или файл настолько большой, что одновременно std::vector и std::map не влезут в память.
кстати, в курсе про вариант вызова std::map::insert() с алгоритмической сложностью O(1)? может быть это может быть решением проблемы перформанса?
31 марта 2010 в 23:02
вопрос, как дождаться завершения потока после его вызова? гуглю не помогает)
31 марта 2010 в 22:04
Какой длины строки?
Если небольшие, то я не понимаю откуда прирос может бытью
31 марта 2010 в 22:04
первый том войны и мира – 3мегабайта )
31 марта 2010 в 22:01
почитай шилда, у него неплохо написана о реализации многопоточности.
31 марта 2010 в 22:01
можно ссылочку пожалуйста?
31 марта 2010 в 21:04
Работа с диском ой какая тормозная, какой тут может быть прирост, кроме константы? а константный прирост – фигня ненужная
31 марта 2010 в 21:03
2Пашка ت Джиоев
при иногда верной работе программы (без семафоров, щас я их напишу попытаюсь), я получаю прирост 3-4 секунды. что очень для меня хорошо.
31 марта 2010 в 21:02
Не думаю, что многопоточное чтение даст прирост производительности, в любом случае чтение надо будет производить последовательно. Вот если бы с каждой считанной строкой надо было производить какие-нибудь трудоемкие действия, то прирост бы был.
31 марта 2010 в 21:02
спасибо. инфу нашел. сейчас попробую.
еще небольшой вопрос:
можно ли миногопоточно перевести данные из <map> в <multimap> ?
как реализовать алгоритм? я что то думал, не знаю.
31 марта 2010 в 20:02
открыть для себя семафоры (или замки — частный случай семафора).
обращаешься к ресурсу (файлу) — закрываешь семафор. Другой поток будет ждать разрешения поработать с ресурсом.
закончил работать с ресурсом — открыл семафор.
А тут у тебя ситуация на грани аппаратного deadlock — в один момент времени только один поток имеет право обладать ресурсом.
22 мая 2021 в 12:24
Медведь, как бы сказать помягче… лучше наводящий вопрос: а какой тип возвращает твоя AfxBeginThread()? Вот, и при чём здесь системный хендл потока?
А ещё учись пользоваться функцией GetLastError() и утилитой ErrorLookup!
P.S.Нормальный Win32 пример тут //www.gamedev.net/community/forums/topic.asp?to...
а тебе надо заюзать это (скопируй ссылку в браузер) //msdn.microsoft.com/en-US/library/afb2xh7f(v=VS.80).aspx