PDA

Просмотр полной версии : [Помогите!] Вложенные циклы


Yukikaze
26.12.2011, 06:22
Помогите пожалуйста, кто сталкивался с вложенными циклами в нескольких потоках?
У меня есть цикл:

while (!loginReader.EndOfStream)
{


username = loginReader.ReadLine();

while (!passwordReader.EndOfStream)
{
lock (locker)
{
pass = passwordReader.ReadLine();
}
log.loginer(username, pass);
main.linesInFile = main.linesInFile + 1;
}
}

который читает строку из первого файла, а потом перебирает все строки во втором. Так вот беда, в один поток это работает на ура, а когда делаю 5-10-15 в общем дофига потоков то цикл накрывается медным тазом, потому что каждый поток пытается взять из первого файла по строке.
Как сделать, что бы из первого файла строка бралась только один раз за цикл, а не умножалась на количество потоков?

ЗЫ Единственное решение которое пришло в голову это добавить ручками N пустых строк в второй фаил и N строк перед каждой строкой в первом О_о
ЗЗЫ И еще один не менее важный вопрос, как выйти из внутреннего цикла если фаил закончился?

while (!loginReader.EndOfStream)
{


username = loginReader.ReadLine();

while (!passwordReader.EndOfStream)
{
lock (locker)
{
pass = passwordReader.ReadLine();
}
log.loginer(username, pass);
main.linesInFile = main.linesInFile + 1;
if (passwordReader.EndOfStream)
{
passwordReader.DiscardBufferedData();
break;
}
}
}


Такой вариант не помогает

Добавлено через 1 час 39 минут
последний вопрос отменяется, какие то в другом месте...найти бы в каком :(
На счет многопоточности еще в силе

Добавлено через 2 часа 4 минуты
Нашел где косяк, кто объяснит, почему вложенный цикл не запускается повторно?
ЗЫ Я конечно догадываюсь, потому, что он закончился, но тогда как сбросить его на исходную позицию?

Добавлено через 2 часа 46 минут
Последнюю проблему решил иницализировав стримридер повторно

if (passwordReader.EndOfStream)
{
passwordReader = new StreamReader(BruteForm.dicBox1);
break;
}

Sinyss
26.12.2011, 15:04
Помогите пожалуйста, кто сталкивался с вложенными циклами в нескольких потоках?

который читает строку из первого файла, а потом перебирает все строки во втором. Так вот беда, в один поток это работает на ура, а когда делаю 5-10-15 в общем дофига потоков то цикл накрывается медным тазом, потому что каждый поток пытается взять из первого файла по строке.
Как сделать, что бы из первого файла строка бралась только один раз за цикл, а не умножалась на количество потоков?

Считать файл в стек и брать данные для потока из него.
Вообще рекомендую наплодить для каждого потока по 1 стеку, в котором сберегается содержание 2го файла, а не считывать его каждый раз. И потоки не будут ждать окончания блокировки от другого потока.
Пускай главный хранит все строки 1го файла, и для каждой строчки создает поток параметром куда идут: ( string <Строка из 1го файла>, Queue <Стек со строками из 2го файла>).
Или сделай еще хитрее:
1й и 2й файл в массивы. дальше работай с ними как для 1го потока в цикле Parallel.For(). // хотя тут не гарантирую, надо проверить, когда писал брутфорсер наткнулся на то что при сравнивании строк оно не всегда выдавало правильный ответ...

Yukikaze
27.12.2011, 04:40
Считать файл в стек и брать данные для потока из него.
Вообще рекомендую наплодить для каждого потока по 1 стеку, в котором сберегается содержание 2го файла, а не считывать его каждый раз. И потоки не будут ждать окончания блокировки от другого потока.
Пускай главный хранит все строки 1го файла, и для каждой строчки создает поток параметром куда идут: ( string <Строка из 1го файла>, Queue <Стек со строками из 2го файла>).
Или сделай еще хитрее:
1й и 2й файл в массивы. дальше работай с ними как для 1го потока в цикле Parallel.For(). // хотя тут не гарантирую, надо проверить, когда писал брутфорсер наткнулся на то что при сравнивании строк оно не всегда выдавало правильный ответ...

Спасибо, покурил мануалы по Parallel.Foreach(), занятная вещица оказалась.


Parallel.ForEach(Global.globalUser,
username =>
{
Parallel.ForEach(Global.globalUser,
pass =>
{
log.loginer(username, pass);
Global.linesInFile = Global.linesInFile + 1;
}
);
}
);


Такой цикл выдает 70ппс в один поток, правда при запуске в несколько потоков оно просто дублирует результат, но по сути как я понял оно само на потоки делит

Добавлено через 1 час 49 минут
хм...постепенно скорость увеличивается, сначала примерно 10-15 ппс, потом быстро растет до 70 и потихоньку прорывается до рекордных 80. Все это конечно неплохо, если бы не одно "НО", как выйти из внутреннего цикла при определенных условиях?

Добавлено через 3 часа 0 минут
Как выйти из внутреннего цикла я разобрался, просто добавил условие с ParallelLoopState.Break()
И сразу новый вопрос, КАК убить эти 2 цикла? Пытался убить процесс в котором они были запущены, но они все равно продолжают жить своей жизнью, да и loopState как то не помогает.

Sinyss
28.12.2011, 01:21
Вынести в отдельную функцию этот цикл и внутри цикла сделать return ?

Yukikaze
28.12.2011, 22:49
Вынести в отдельную функцию этот цикл и внутри цикла сделать return ?

В принципе спасибо за совет, но я уже закончил, на моем стареньком Core 2 Duo e8650 при 1мб/с аплод получаю около 80 ппс, у друга на Phenom II x4 идет больше 100.

nicolaiv007
14.01.2012, 09:46
действительно старенький