Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
 Аватар для awp-sirius
64 / 63 / 43
Регистрация: 01.05.2012
Сообщений: 535
.NET 4.x

И снова многопоточность

01.06.2014, 02:13. Показов 2788. Ответов 36
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброй ночи всем!

Я уже понял, что это ооочень заезженная тема "многопоточность")

Полностью просмотрел урок (2 часа) http://www.youtube.com/watch?v=strsTAfcAv4

Основы-то понял, но как именно реализовать мою задачу пока не совсем понимаю...
А задача в следующем:
Имеется какой-то длинный массив строк. Ну и используем к примеру 10 потоков.

Должно происходить что-то следующее:
1-й поток берёт себе 1-ю строку массива, 2-й вторую и так далее. НО время выполнения может быть разное, и если первые 9 потоков ещё выполняют задачу, а 10-й поток уже выполнил мвою 10-ю строку, то он должен брать следующую строку массива (11-ю).
И так соответственно все остальные. (Не блещу умением объяснять))

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

Сложность с тем, что бы 2 потока не взяли один и тот же элемент...

Весь день читаю статьи и не могу точно найти ответ на поставленную задачу. И при помощи чего делать..
Почему-то кажется что подойдёт пул потоков.. Или может через Parallel.For?

Скорее всего буду делать WidowsForms, поэтому может быть использовать BackgroundWorker?..

В общем подскажите пожалуйста... Уже очень долго мучаюсь..

P.S. Заранее отвечу на вопрос, программа ProxyChecker.. Просто встала задача под определённый сайт. Саму проверку прокси уже реализовал, вот теперь мучаюсь, что бы ускорить сее творение.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.06.2014, 02:13
Ответы с готовыми решениями:

И снова про многопоточность
Доброго времени суток, форумчане, задался целью немного переделать программу для более быстрой работы Итак, что мы имеем: массив картинок...

Снова многопоточность: совместный доступ к объекту
Добрый день. Начал самостоятельно изучать Java. Дойдя до вопросов многопоточности, решил написать тестовую программу, в которой класс...

Снова хром, снова сапопроизвольно открывается, снова bkrfdf.xyz и казино
Здравствуйте! Собственно, проблема уже не новая, хотя, как показывают сообщения форума, за последние дни выскочившая у многих. Через...

36
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
01.06.2014, 12:49
awp-sirius,
  • пул потоков - это то, что нужно.
  • Parallel.ForEach - то же самое, что пул(в частности он сам его использует), но в более приятном виде (например, не нужно ставить самому ManualResetEvent чтобы дождаться выполнения всех потоков).
  • BackgroundWorker - фактически один фоновый поток, для задачи подходит, только чтобы не замораживать основной поток.
0
169 / 132 / 29
Регистрация: 16.02.2013
Сообщений: 867
01.06.2014, 13:39
Psilon, а почему бы не использовать lock и очередь к примеру?
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
01.06.2014, 13:44
Winhttp22, потому что они тормознутые?..
1
 Аватар для Anklav
447 / 305 / 47
Регистрация: 23.01.2013
Сообщений: 661
01.06.2014, 13:44
Ну лок здесь с очередью точно не нужен. Хватит одного инта и Interlocked.Increment.
1
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
01.06.2014, 13:58
тем более, что тредпул был разработан специально для решения таких задач. Глупо было бы после этого его не использовать

Добавлено через 12 секунд
Anklav, да

Добавлено через 6 минут
Anklav, кстати у меня был тест помню, так lock с обычным i++ был быстрее, чем interlocked. Так что с точки зрения производительности lock выигрывает о_0

Добавлено через 7 минут
хотя не всегда. Зависит от числа потоков
0
 Аватар для awp-sirius
64 / 63 / 43
Регистрация: 01.05.2012
Сообщений: 535
01.06.2014, 15:10  [ТС]
Psilon, Спасибо, а можно какой-нибудь пример использования Thread Pool или Parallel.For именно для похожей задачи?

Winhttp22, сначала и пытался использовать lock:

Кликните здесь для просмотра всего текста
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
 
namespace ConsoleApplication1
{
    class Program
    {
        object block = new object();
 
        static void Main(string[] args)
        {
 
            Program instance = new Program();
 
            for (int t = 0; t < 5; t++)
            {
                new Thread(instance.Perebor).Start();
            }
 
            Console.ReadKey();
        }
 
        public void Perebor()
        {
            int i = 0;
            lock (block)
            {
                i++;
            }
            Check(i);
        }
 
        public void Check(int i)
        {
            //какая-то долгая операция
            Console.WriteLine(i);
        }
    }
}


Однако переменные в потоках получаются "разные", что бы один поток не делал с i, у второго потока значение для его переменно i не изменится.
0
 Аватар для awp-sirius
64 / 63 / 43
Регистрация: 01.05.2012
Сообщений: 535
01.06.2014, 15:34  [ТС]
Пробую использовать Parallel.For:

Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace ConsoleApplication1
{
    class Program
    {
        object block = new object();
 
        static void Main(string[] args)
        {
            Parallel.For(0, 50, i => Check(i));
 
            Console.ReadKey();
        }
 
        static void Check(long i)
        {
            //какая-то долгая операция
            Console.WriteLine(i);
        }
    }
}


Получается следующее:


Как я понимаю у меня создалось 50 потоков... Как это количество ограничить?...
К примеру цикл не до 50-ти, а до 10000, и я хочу, что бы выделялось 20 потоков, они выполнялись, как только поток освобождается выполняет следующую задачу
0
169 / 132 / 29
Регистрация: 16.02.2013
Сообщений: 867
01.06.2014, 15:50
Цитата Сообщение от awp-sirius Посмотреть сообщение
Однако переменные в потоках получаются "разные", что бы один поток не делал с i, у второго потока значение для его переменно i не изменится.
так вы обьявляете локальную переменную в каждом потоке, и хотите, чтобы ее значение изменяли другие потоки?

C#
1
2
3
4
5
6
7
8
9
        public void Perebor()
        {
            int i = 0;
            lock (block)
            {
                i++;
            }
            Check(i);
        }
а если так попробовать -
Кликните здесь для просмотра всего текста
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
 
namespace ConsoleApplication1
{
    class Program
    {
        object block = new object();
        int i = 0;
            
 
        static void Main(string[] args)
        {
 
            Program instance = new Program();
 
            for (int t = 0; t < 5; t++)
            {
                new Thread(instance.Perebor).Start();
            }
 
            Console.ReadKey();
        }
 
        public void Perebor()
        {
            lock (block)
            {
                i++;
            }
            Check(i);
        }
 
        public void Check(int i)
        {
            //какая-то долгая операция
            Console.WriteLine(i);
        }
    }
}
то норм будет?
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
01.06.2014, 16:45
Winhttp22, никогда, никогда, никогда не работай с потоками вручную, самый низкоуровневый интерфейс для многопоточности - пул.

awp-sirius, пожалуйста, пример с пулом:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
        private static IList<Predicate<byte[]>> CheckAsync(byte[] file, params Predicate<byte[]>[] predicates)
        {
            var result = new List<Predicate<byte[]>>(predicates.Length);
            var allDone = new ManualResetEvent(false);
            int completed = 0;
            foreach (var p in predicates)
            {
                Predicate<byte[]> currentCheck = p;
                ThreadPool.QueueUserWorkItem(_ =>
                                             {
                                                 if (currentCheck(file))
                                                     lock (result)
                                                     {
                                                         result.Add(currentCheck);
                                                     }
                                                 if (Interlocked.Increment(ref completed) == predicates.Length)
                                                     allDone.Set();
                                             });
            }
            allDone.WaitOne();
            return result;
        }
0
 Аватар для Anklav
447 / 305 / 47
Регистрация: 23.01.2013
Сообщений: 661
01.06.2014, 16:47
Psilon, при использовании лока плохо будет когда контекст переключится, а старый поток останется внутри лока, тогда остальные потоки будут сосать лапу. С неблокирующими операциями такого не случится.
1
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
01.06.2014, 17:04
Anklav, не спорю Interlocked лучше использовать всегда, когда возможно.
0
 Аватар для awp-sirius
64 / 63 / 43
Регистрация: 01.05.2012
Сообщений: 535
01.06.2014, 17:08  [ТС]
Psilon, Если честно... Не совсем понял...
Как использовать Parallel.For именно для похожей задачи?
Ну что бы ограничить количество потоков

Добавлено через 2 минуты
Меня устраивает результат, который получался вот с печатью цифр от 0 до 99, пусть не по порядку, но повторений нет и ничего не выскакивает.

Просто увеличение числа потоков != увеличение производительности.
0
169 / 132 / 29
Регистрация: 16.02.2013
Сообщений: 867
01.06.2014, 17:11
Цитата Сообщение от Psilon Посмотреть сообщение
Winhttp22, никогда, никогда, никогда не работай с потоками вручную, самый низкоуровневый интерфейс для многопоточности - пул.
почему? И что значит - "вручную"?
0
 Аватар для m0nax
1274 / 975 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
01.06.2014, 17:15
Цитата Сообщение от awp-sirius Посмотреть сообщение
Ну что бы ограничить количество потоков
для этого нужна очередь и ручное управление потоками, а все описанное выше бесполезно
делаешь Х потоков, в каждом лочишь очередь, достаешь 1 элемент и обрабатываешь
0
 Аватар для awp-sirius
64 / 63 / 43
Регистрация: 01.05.2012
Сообщений: 535
01.06.2014, 17:18  [ТС]
m0nax, значит приблизительно то, что предложил Winhttp22?
0
169 / 132 / 29
Регистрация: 16.02.2013
Сообщений: 867
01.06.2014, 17:27
Цитата Сообщение от m0nax Посмотреть сообщение
для этого нужна очередь и ручное управление потоками, а все описанное выше бесполезно
делаешь Х потоков, в каждом лочишь очередь, достаешь 1 элемент и обрабатываешь
так в пуле можно же указать количество потоков через метод ThreadPool.SetMaxThreads ?

Добавлено через 5 минут
Цитата Сообщение от awp-sirius Посмотреть сообщение
Меня устраивает результат, который получался вот с печатью цифр от 0 до 99, пусть не по порядку, но повторений нет и ничего не выскакивает.
чтобы по порядку было - то тебе нужно не только один инкремент переменной локать, а и вывод в консоль. Тогда будет по порядку
0
 Аватар для awp-sirius
64 / 63 / 43
Регистрация: 01.05.2012
Сообщений: 535
01.06.2014, 17:35  [ТС]
Winhttp22, порядок не важен..
в общем нужно использовать ThreadPool, а не Parallel.For?
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
01.06.2014, 18:39
awp-sirius, уж определись, что тебе хочется. Параллельный вывод чисел от 1 до 99? Пожалуйста:
C#
1
Parallel.For(1, 100, Console.WriteLine);
Если это не то - уточняйте лучше.

Добавлено через 2 минуты
Цитата Сообщение от Winhttp22 Посмотреть сообщение
почему? И что значит - "вручную"?
вручную, это new Thread()
Цитата Сообщение от awp-sirius Посмотреть сообщение
Просто увеличение числа потоков != увеличение производительности.
Parallel определяет сам оптимальное число потоков. Его можно выставлять и вручную, но быстрее автоматически рассчитанного значения вряд ли получится, а вот медленнее - легко.
0
 Аватар для awp-sirius
64 / 63 / 43
Регистрация: 01.05.2012
Сообщений: 535
01.06.2014, 19:34  [ТС]
Цитата Сообщение от Psilon Посмотреть сообщение
Parallel определяет сам оптимальное число потоков. Его можно выставлять и вручную, но быстрее автоматически рассчитанного значения вряд ли получится, а вот медленнее - легко.
Ааааааааааааааааааааааааааа)

Вот можно в ручную:
ThreadPool.SetMaxThreads(int workerThreads, int completionPortThreads), но что такое int completionPortThreads?
На msdn написано, но как-то не понятно..


Цитата Сообщение от Psilon Посмотреть сообщение
Если это не то - уточняйте лучше.
Я там писал, хочу сделать Proxy Checker (проверка прокси серверов на валидность к определённому сайту)

То есть будет массив из скольких-то элементов. Каждый поток должен брать один элемент (ip proxy) и проверять его. Это занимает время (ожидание отклика).

Вся проблема в том, что бы 2 потока не взяли один и тот же элемент массива.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
01.06.2014, 19:34
Помогаю со студенческими работами здесь

Как сделать чтобы таймер дойдя до 0 стартовал снова и снова?
Здравствуйте :) Как сделать чтобы таймер дойдя до 0 стартовал снова и снова? TimerSec = 59; TimerMin = 6; for(int i = TimerSec;...

HP 625 снова и снова перезагружается в безопасный не заходит
Ребята помогите , проблема вот какая врубаю я ноут он доходит до заставки майкрософта и снова перезагружается в безопасный не заходит, ...

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

и снова .htaccess и снова rewriterule
Добрый день. Недавно столкнулся с проблемой преобразования URL, в связи с чем пришлось перерыть кучу материала по данной теме, но вопрос...

Снова. Снова этот repaint()
Всем привет. Сколько дней уже пытаюсь, нечего не выходит. Метод repaint не срабатывает. Как я понимаю, ошибка появляется в методе redraw...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
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 18.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 секунды (а то и больше),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru