ThreadPool проблема зависания
От: zoom-zoom  
Дата: 12.01.15 12:08
Оценка: :))
День добрый!
Нужен был таймер сверхбыстрый, решил проблему с помощью while, который работает в отдельном потоке:

private static AutoResetEvent autoEvent1 = new AutoResetEvent(false);
private static AutoResetEvent autoEvent2 = new AutoResetEvent(false);
bool b1 = false;
bool b2 = false;
private void button_Click(object sender, EventArgs e)
{
  b1 = true;
  ThreadPool.QueueUserWorkItem(new WaitCallback(tread1), autoEvent1);
  b2 = true;
  ThreadPool.QueueUserWorkItem(new WaitCallback(tread2), autoEvent2);
}
private void tread1(object state)
{
  while (b1)
  {
    ... //вычисления
    Thread.Sleep(1);
    ((AutoResetEvent)state).Set();
  }
}
private void tread2(object state)
{
  while (b2)
  {
    ... //вычисления
    Thread.Sleep(1);
    ((AutoResetEvent)state).Set();
  }
}


После достаточно продолжительного времени, более 2-х часов работы все приложение WinForm зависает.
Работаю в VS2010. Запускаю приложение в отладчике. При зависании приложения нажимаю на Паузу, остановка идет на каком-либо Thread.Sleep(1).
Дальнейшее пошаговое выполнение идет только по одному циклу while, например в tread1, в другой поток tread2 не заходит. Не пойму, как такое может быть и как это исправить?
Отредактировано 12.01.2015 12:33 zoom-zoom . Предыдущая версия . Еще …
Отредактировано 12.01.2015 12:27 zoom-zoom . Предыдущая версия .
Re: [оффтоп] Оформление
От: xobotik Россия  
Дата: 12.01.15 12:15
Оценка: -2
Здравствуйте, zoom-zoom, Вы писали:

Оформите Ваше сообщение нормальным образом! Нет желания читать даже, когда не оформлено.
С уважением!
Re: ThreadPool проблема зависания
От: hardcase Пират http://nemerle.org
Дата: 12.01.15 12:42
Оценка: +1
Здравствуйте, zoom-zoom, Вы писали:

ZZ>День добрый!

ZZ>Нужен был таймер сверхбыстрый, решил проблему с помощью while, который работает в отдельном потоке:

Почему не подошел System.Threading.Timer?
/* иЗвиНите зА неРовнЫй поЧерК */
Re: ThreadPool проблема зависания
От: koodeer  
Дата: 12.01.15 12:58
Оценка: +2
Здравствуйте, zoom-zoom, Вы писали:

ZZ> ThreadPool

ZZ> более 2-х часов работы

Потоки из пула следует использовать только для коротких операций. Если вычисления длительные, лучше создать отдельный поток(и). Пока потоки из пула долго заняты в одном приложении, может начаться их нехватка во всей системе.
Re[2]: ThreadPool проблема зависания
От: zoom-zoom  
Дата: 12.01.15 13:22
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, zoom-zoom, Вы писали:


ZZ>>День добрый!

ZZ>>Нужен был таймер сверхбыстрый, решил проблему с помощью while, который работает в отдельном потоке:

H>Почему не подошел System.Threading.Timer?


Timer тоже тестировал, но с while работает быстрее, когда запускается потоков более 10.
Re[2]: ThreadPool проблема зависания
От: zoom-zoom  
Дата: 12.01.15 13:34
Оценка:
Здравствуйте, koodeer, Вы писали:

K>Здравствуйте, zoom-zoom, Вы писали:


ZZ>> ThreadPool

ZZ>> более 2-х часов работы

K>Потоки из пула следует использовать только для коротких операций. Если вычисления длительные, лучше создать отдельный поток(и). Пока потоки из пула долго заняты в одном приложении, может начаться их нехватка во всей системе.


Да, программа может работать несколько дней без перерыва, это биржевой торговый робот под Плаза2 (может кто-то знаком с этим). Нужно создать 15 потоков независимых, чтобы не грузили ЦП и быстро, не более 1 мс, производили прокачку данных с сервера. Таймеров с частотой менее 1мс нет, самое быстрое — это цикл while, но нужно запускать его в отдельном потоке, фоновом, т.е. в 15 отдельных потоках.
Re[3]: ThreadPool проблема зависания
От: pugv Россия  
Дата: 12.01.15 14:07
Оценка:
Здравствуйте, zoom-zoom, Вы писали:

ZZ> Нужно создать 15 потоков независимых


В чем проблема? new Thread().

ZZ> чтобы не грузили ЦП


Это уже зависит от того, что они будут делать

ZZ> быстро, не более 1 мс, производили прокачку данных с сервера.


Сильно подозреваю, что сама прокачка данных с сервера будет занимать больше 1мс.

ZZ> Таймеров с частотой менее 1мс нет


Есть. Multimedia Timers, QueryPerformanceCounter, например.

ZZ> самое быстрое — это цикл while


Вы сильно удивитесь, если честно померяете сколько спит поток на Вашем Sleep(1).
Re[4]: ThreadPool проблема зависания
От: zoom-zoom  
Дата: 12.01.15 14:29
Оценка:
Здравствуйте, pugv, Вы писали:

ZZ>> чтобы не грузили ЦП

P>Это уже зависит от того, что они будут делать

Если в потоке Thread запускаю даже пустой цикл while, то загрузка ЦП с 1 потока увеличивается с 1 до 25%. Не знаю, как решить эту проблему без использования Sleep().

ZZ>> быстро, не более 1 мс, производили прокачку данных с сервера.

P>Сильно подозреваю, что сама прокачка данных с сервера будет занимать больше 1мс.

Это уже не важно, главное чтобы между запросами к серверу было как можно меньше времени, так как там информация скапливается в больших объемах, чем чаще качаешь, тем лучше.

ZZ>> Таймеров с частотой менее 1мс нет

P>Есть. Multimedia Timers, QueryPerformanceCounter, например.

Спасибо за информацию.

ZZ>> самое быстрое — это цикл while

P>Вы сильно удивитесь, если честно померяете сколько спит поток на Вашем Sleep(1).

Да, теряется много больше 1мс. Я переделал только что с пулов на Thread, все равно пришлось добавить Sleep(1), чтобы не грузить ЦП. Выиграл в разы по времени по сравнению с ThreadPool на 2-х потоках, надо все 15 проверить, а то может будет хуже.
Re[3]: ThreadPool проблема зависания
От: TK Лес кывт.рф
Дата: 12.01.15 14:35
Оценка: +1
Здравствуйте, zoom-zoom, Вы писали:

ZZ>Да, программа может работать несколько дней без перерыва, это биржевой торговый робот под Плаза2 (может кто-то знаком с этим). Нужно создать 15 потоков независимых, чтобы не грузили ЦП и быстро, не более 1 мс, производили прокачку данных с сервера. Таймеров с частотой менее 1мс нет, самое быстрое — это цикл while, но нужно запускать его в отдельном потоке, фоновом, т.е. в 15 отдельных потоках.


Для выполнения действий каждую 1мс надо ставить потоку realtime приоритет (т.е с вашим подходом число физических ядер должно быть больше 15).

The length of the clock interval varies according to the hardware platform. The frequency of the clock interrupts is up to the HAL, not the kernel. For example, the clock interval for most x86 uniprocessors is 10 milliseconds, and for most x86 multiprocessors, 15 milliseconds.


у вас либо неверный инструмент либо надо пересмотреть подход.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[5]: ThreadPool проблема зависания
От: pugv Россия  
Дата: 12.01.15 14:38
Оценка:
Здравствуйте, zoom-zoom, Вы писали:

ZZ>Если в потоке Thread запускаю даже пустой цикл while, то загрузка ЦП с 1 потока увеличивается с 1 до 25%. Не знаю, как решить эту проблему без использования Sleep().


Естественно, или Вы думали, что цикл выполняется не на процессоре?

ZZ>Это уже не важно, главное чтобы между запросами к серверу было как можно меньше времени, так как там информация скапливается в больших объемах, чем чаще качаешь, тем лучше.


Так не ждите вообще никакого времени, раз нужно как можно меньше. Запросы в цикле.

ZZ> Я переделал только что с пулов на Thread, все равно пришлось добавить Sleep(1), чтобы не грузить ЦП.


Если есть одновременно требования "между запросами к серверу было как можно меньше времени" и "чтобы не грузить ЦП", то квотируйте, есть средства начиная со Sleep, через SetPriorityClass/SetThreadPriority, и до job objects (это, правда, в последних ОС только).
Re[5]: ThreadPool проблема зависания
От: TK Лес кывт.рф
Дата: 12.01.15 14:43
Оценка: +1
Здравствуйте, zoom-zoom, Вы писали:

ZZ>Если в потоке Thread запускаю даже пустой цикл while, то загрузка ЦП с 1 потока увеличивается с 1 до 25%. Не знаю, как решить эту проблему без использования Sleep().


Скорее всего у вас четырех ядерный процессор. Sleep приводит к возврату оставшегося кванта времени. т.е. спать поток будет больше чем 1мс

ZZ>Это уже не важно, главное чтобы между запросами к серверу было как можно меньше времени, так как там информация скапливается в больших объемах, чем чаще качаешь, тем лучше.


Оптимизируйте скачивание. качайте одним потоком но, постоянно.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[6]: ThreadPool проблема зависания
От: zoom-zoom  
Дата: 12.01.15 18:48
Оценка:
Здравствуйте, TK, Вы писали:

TK>Здравствуйте, zoom-zoom, Вы писали:


ZZ>>Если в потоке Thread запускаю даже пустой цикл while, то загрузка ЦП с 1 потока увеличивается с 1 до 25%. Не знаю, как решить эту проблему без использования Sleep().


TK>Скорее всего у вас четырех ядерный процессор. Sleep приводит к возврату оставшегося кванта времени. т.е. спать поток будет больше чем 1мс


ZZ>>Это уже не важно, главное чтобы между запросами к серверу было как можно меньше времени, так как там информация скапливается в больших объемах, чем чаще качаешь, тем лучше.


TK>Оптимизируйте скачивание. качайте одним потоком но, постоянно.


Сделал 1 потоком, но осталась проблема загрузки ЦП, Sleep решал проблему, может есть альтернатива более профессиональная?
Re: ThreadPool проблема зависания
От: scale_tone Норвегия https://scale-tone.github.io/
Дата: 12.01.15 21:38
Оценка: +1
Здравствуйте, zoom-zoom, Вы писали:

ZZ>При зависании приложения нажимаю на Паузу, остановка идет на каком-либо Thread.Sleep(1).

ZZ>Дальнейшее пошаговое выполнение идет только по одному циклу while, например в tread1, в другой поток tread2 не заходит. Не пойму, как такое может быть и как это исправить?

Что именно Вы хотите исправить?

Зависание приложения? Виснет у Вас, очевидно, GUI-поток. И, хоть и приведенный код (как уже сказали) ужасен, это зависание с ним (с этим конкретным куском кода) почти наверняка не связано. Вы же сами говорите: пошаговое выполнение идет. А если б рабочий поток завис — оно не шло бы.
Чтобы строить предположения о починке зависания GUI-потока надо для начала понять, на чем виснет он.

То, что при break-е после зависания Вы всегда попадаете на строку Thread.Sleep()? Вы туда всегда попадаете просто потому, что рабочий поток проводит там бОльшую часть времени. Вряд ли это нужно исправлять.

То, что при break-е после зависания происходит пошаговое выполнение одного и того же потока? Исправить это так: научиться пользоваться отладчиком, выбрать в списке потоков нужный и отладить его.
Re[7]: ThreadPool проблема зависания
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 12.01.15 23:34
Оценка:
Здравствуйте, zoom-zoom, Вы писали:

TK>>Оптимизируйте скачивание. качайте одним потоком но, постоянно.


ZZ>Сделал 1 потоком, но осталась проблема загрузки ЦП, Sleep решал проблему, может есть альтернатива более профессиональная?


Конечно есть. Не использовать thread pool, отдельные потоки и подобную ересь, это слишком сложно, чтобы можно было сделать и поддерживать в работоспособном состоянии.

Используйте асинхронный ввод-вывод и TPL, а еще лучше RX, он прекрасно подходит для обработки потока сигналов от биржи.
Re[7]: ThreadPool проблема зависания
От: ionoy Эстония www.ammyui.com
Дата: 13.01.15 07:10
Оценка: 1 (1)
Здравствуйте, zoom-zoom, Вы писали:

ZZ>Сделал 1 потоком, но осталась проблема загрузки ЦП, Sleep решал проблему, может есть альтернатива более профессиональная?


Есть SpinWait, но тут уже зависит от того, насколько часто вам нужно читать данные.

А, вообще, загрузка данных с сервера это IO операция которую можно ждать через await.

Упрощённо, как-то так:

public async Task StartReadingDataFrom(string url) 
{
  var client = new HttpClient();
  while(true) {
    var str = await client.GetStringAsync(url);
    _receivedData.Enqueue(str);
  }
}


В таком случае вам не придётся создавать поток вручную.
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Отредактировано 13.01.2015 7:11 ionoy . Предыдущая версия .
Re[8]: ThreadPool проблема зависания
От: zoom-zoom  
Дата: 13.01.15 07:45
Оценка:
Здравствуйте, ionoy, Вы писали:

I>Здравствуйте, zoom-zoom, Вы писали:


ZZ>>Сделал 1 потоком, но осталась проблема загрузки ЦП, Sleep решал проблему, может есть альтернатива более профессиональная?


I>Есть SpinWait, но тут уже зависит от того, насколько часто вам нужно читать данные.


I>А, вообще, загрузка данных с сервера это IO операция которую можно ждать через await.


I>Упрощённо, как-то так:


I>
I>public async Task StartReadingDataFrom(string url) 
I>{
I>  var client = new HttpClient();
I>  while(true) {
I>    var str = await client.GetStringAsync(url);
I>    _receivedData.Enqueue(str);
I>  }
I>}
I>


I>В таком случае вам не придётся создавать поток вручную.


Это точно не вариант, там определенная структура получения данных. в цикле while нужно совершать вызов cg_conn_process(uint32_t timeout).
Данный вызов осуществляет итерацию работы с соединением, которая включает в себя опрос очереди входящих сообщений, анализ
пришедших данных, вызов пользовательских функций обратного вызова. Эта функция должна вызываться из кода пользователя с
частотой, соответствующей максимальной желаемой частоте получения данных. Рекомендуют timeout=0.
Re[9]: ThreadPool проблема зависания
От: Qulac Россия  
Дата: 13.01.15 07:55
Оценка:
Здравствуйте, zoom-zoom, Вы писали:

ZZ>Здравствуйте, ionoy, Вы писали:


I>>Здравствуйте, zoom-zoom, Вы писали:


ZZ>>>Сделал 1 потоком, но осталась проблема загрузки ЦП, Sleep решал проблему, может есть альтернатива более профессиональная?


I>>Есть SpinWait, но тут уже зависит от того, насколько часто вам нужно читать данные.


I>>А, вообще, загрузка данных с сервера это IO операция которую можно ждать через await.


I>>Упрощённо, как-то так:


I>>
I>>public async Task StartReadingDataFrom(string url) 
I>>{
I>>  var client = new HttpClient();
I>>  while(true) {
I>>    var str = await client.GetStringAsync(url);
I>>    _receivedData.Enqueue(str);
I>>  }
I>>}
I>>


I>>В таком случае вам не придётся создавать поток вручную.


ZZ>Это точно не вариант, там определенная структура получения данных. в цикле while нужно совершать вызов cg_conn_process(uint32_t timeout).

ZZ>Данный вызов осуществляет итерацию работы с соединением, которая включает в себя опрос очереди входящих сообщений, анализ
ZZ>пришедших данных, вызов пользовательских функций обратного вызова. Эта функция должна вызываться из кода пользователя с
ZZ>частотой, соответствующей максимальной желаемой частоте получения данных. Рекомендуют timeout=0.

Если Вы будете использовать асинхронность, то данные будут обрабатываться сразу как только были получены, и все это без всяких блокировок и приостановки потоков. Только архитектуру нужно продумать.
Программа – это мысли спрессованные в код
Re[9]: ThreadPool проблема зависания
От: TK Лес кывт.рф
Дата: 13.01.15 08:08
Оценка:
Здравствуйте, zoom-zoom, Вы писали:

ZZ>Это точно не вариант, там определенная структура получения данных. в цикле while нужно совершать вызов cg_conn_process(uint32_t timeout).

ZZ>Данный вызов осуществляет итерацию работы с соединением, которая включает в себя опрос очереди входящих сообщений, анализ
ZZ>пришедших данных, вызов пользовательских функций обратного вызова. Эта функция должна вызываться из кода пользователя с
ZZ>частотой, соответствующей максимальной желаемой частоте получения данных. Рекомендуют timeout=0.

Тогда отдайте одно ядро под чтение данных (если реально нужна реакция с такой частотой) — ничего страшного в этом нет (если опрос не будет перегружать отдающий сервер). Другой вариант зачем в этой точке .net — неожиданно пришедшая сборка мусора внесет вам непредсказуемые задержки.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[8]: ThreadPool проблема зависания
От: TK Лес кывт.рф
Дата: 13.01.15 08:10
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Используйте асинхронный ввод-вывод и TPL, а еще лучше RX, он прекрасно подходит для обработки потока сигналов от биржи.


Если стоит задача среагировать в пределах до 10мс то, не особо....
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[9]: ThreadPool проблема зависания
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 13.01.15 08:56
Оценка: +1
Здравствуйте, TK, Вы писали:

TK>Здравствуйте, gandjustas, Вы писали:


G>>Используйте асинхронный ввод-вывод и TPL, а еще лучше RX, он прекрасно подходит для обработки потока сигналов от биржи.


TK>Если стоит задача среагировать в пределах до 10мс то, не особо....


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

Разгуливание подобных проблем приведет как раз к созданию своего варианта TPL и\или Rx, только гораздо медленнее и с кучей багов.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.