Задать вопрос

Как правильно создать >=1000 потоков?

Дано: есть база данных на PostgreSQL, в который есть 2 хранимые процедуры. Есть консолька на C# с драйвером Npgsql. В консольке надо создать 1000 потоков, каждый из которых имеет своё соединение и вызывает эти самые хранимки. Вызываю потоки и запрос следующим образом:
new Thread(() =>
                {
                    Thread.CurrentThread.IsBackground = true;
                    for (var i = 0; i < 500; i++) {
                        try {
                            var thread = new Thread(() =>
                            {
                                Console.WriteLine($"Running thread: {Thread.CurrentThread.ManagedThreadId}");
                                SaveByteA(connectionString);
                                var a = 2 + 4;
                            }) {IsBackground = true,Priority = ThreadPriority.AboveNormal};
                            thread.Start();
                        }
                        catch (Exception e) {
                            Console.WriteLine(e);
                            throw;
                        }
                    }

                    Console.WriteLine("Finished Thread #1.");

                })
                { IsBackground = true, Priority = ThreadPriority.Highest }.Start();


                new Thread(() =>
                {
                    Thread.CurrentThread.IsBackground = true;
                    for (var i = 0; i < 500; i++)
                    {
                        try {
                            var thread = new Thread(() =>
                                {
                                    Console.WriteLine($"Running  2 thread: {Thread.CurrentThread.ManagedThreadId}");
                                    SaveByteB(connectionString);

                                })
                                { IsBackground = true, Priority = ThreadPriority.AboveNormal };
                            thread.Start();
                        }
                        catch (Exception e) {
                            Console.WriteLine(e);
                            throw;
                        }
                    }
                    Console.WriteLine("Finished Thread #2.");
                }) { IsBackground = true, Priority = ThreadPriority.Highest}.Start();

Надо: Сделать столько запросов (то бишь потоков), чтобы одновременное количество соединённых клиентов с выполняющимися транзакциями было примерно ~1000.
Проблема :когда запускаю консольку с малым количеством потоков, то всё обрабатывается быстро -- БД очень мощная, поэтому результат в ~1000 соединении и обрабатываемых транзакции пропадает. А когда ставлю большое количество потоков, то получаю SocketException -- соединение было прервано насильно удалённым хостом. (Приём консколька жалуется на базу, а база на клиент. кто прав -- не пойму).

В чём моя проблема? Куда копать? Есть лучше варианты работы с потоками или варианты нагрузки базы так, как написано в условии?
  • Вопрос задан
  • 1663 просмотра
Подписаться 7 Простой 3 комментария
Решения вопроса 1
@alexs0ff
Если у Вас компьютер не 1000 ядерный, вам нужны не CPU bound потоки, а IO bound потоки. Поищите асинхронные методы в вашем PostgesQl провайдере (скорее всего они с приставкой Sync)
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
profesor08
@profesor08
Похоже на первый опыт ддоса своей бд. Распредели нагрузку так, чтоб число соединений в секунду не превышало лимита, на который настроена бд. И все получится.
Ответ написан
Комментировать
sentike
@sentike
Программист, разработчик игр, студент
Макс Максимов, посмотри сколько одновременных соединений разрешено у БД. Если мало, то увеличь.
https://stackoverflow.com/questions/30778015/how-t...

Так же почитай документацию на драйвер: www.npgsql.org/doc/connection-string-parameters.html
Тебя должно интересовать Pooling. Попробуй так же увеличь количество зарезервированных подключений.

Pooling=true;Min Pool Size=0;Max Pool Size=1000;


Помониторь на каком потоке происходит исключение, узнай его индекс. Добавь временную переменную или как угодно отследи его. Если вылетает на одном и том же или +-, то скорее всего смотри начало ответа).
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы