Страница: 1 |
|
Вопрос: System грузит ЦП при активной работе с сокетами
|
Добавлено: 06.07.12 18:14
|
|
Автор вопроса: Programmer
|
Добрый день!
Запускаю сервер и клиент (самописные), они создают 2000-3000 локальных TCP соединений и передают 4 мбайт/с на все соединения в сумме.
Сервер грузит 25-30%, клиент тоже. При этом System начинает активно использовать ЦП - 30%. На Windows 7 общая нагрузка 100%, на XP ситуация гораздо лучше, но проблема тоже есть.
На одном форуме советовали отключить управление электропитанием для сетевой карты в диспетчере устройств. На ХР вроде помогло (System грузит ЦП, но меньше), на Windows 7 все осталось как было.
XP и Win 7 на разных компах. Там, где сейчас Win 7 раньше работала XP - ситуация была аналогичная с компом, на котором сейчас XP. Т.е. дело не в железе.
Еще кое что: когда я попробовал создать на Win 7 больше соединений, сначала погас экран, потом вылетел BSOD "BAD_POOL_CALLER". На Win XP все нормально.
С сокетами работаю асинхронно. В отдельном потоке периодически обхожу все соединения и вызываю BeginReceive (только там, где предыдущие данные приняты). Данные храню в буфере и отправляю синхронным Send-ом из того же потока.
В чем может быть проблема?
Заранее спасибо за помощь!
Ответить
|
Номер ответа: 7 Автор ответа: Programmer
Вопросов: 71 Ответов: 246
|
Профиль | | #7
|
Добавлено: 07.07.12 13:07
|
Вот код обработки
- class ProcessingClientsTask
- {
- public int Max;
- public int Min;
- public bool Completed;
-
- public ProcessingClientsTask(int min, int max)
- {
- this.Max = max;
- this.Min = min;
- }
- }
-
-
- #region Static processing
-
- static List<TCPClient> AllClients = new List<TCPClient>();
- static ReaderWriterLockSlim AllClientsListLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
-
- //#region Static processing
- private static object processingLockObj = new object();
- private static Thread processingThread;
-
- static void ProcessClients(object state)
- {
- var task = (ProcessingClientsTask)state;
- try
- {
- int min = task.Min;
- if (min < 0) min = 0;
- int i = task.Max + 1;
- while (--i >= min)
- {
- if (i >= AllClients.Count) i = AllClients.Count - 1;
- TCPClient cl;
- try
- {
- cl = AllClients;
- }
- catch { continue; } // IndexOutOfRangeException or ArgumentOutOfrAngeException
-
- try
- {
- if (cl.lastFlush.ElapsedMilliseconds >= cl.FlushPeriod) cl.Flush();
-
- if (!cl.Disposed && cl._needBeginReceive.IsRunning && (cl._needBeginReceive.ElapsedMilliseconds > cl._needBeginReceiveWait))
- {
- cl.BeginReceive();
- }
- }
- catch (Exception e)
- {
- cl.CallOnException(e);
- }
- }
- }
- catch (Exception e)
- {
- Utils.TraceException("ProcessClients", e);
- }
- finally
- {
- task.Completed = true;
- }
- }
-
- static void DoProcessing()
- {
- #if DEBUG
- Console.WriteLine("TCPClients processing started");
- #endif
- StopwatchInt startedAt = StopwatchInt.StartNew();
- while (AllClients.Count != 0)
- {
- int sleepTime = ProcessingPeriod - startedAt.ElapsedMilliseconds;
- if (sleepTime < 5) sleepTime = 5;
- Thread.Sleep(sleepTime);
- startedAt.Restart();
-
- int clientsPerThread = ClientsPerThread;
- if (clientsPerThread <= 10) clientsPerThread = 10;
-
- //AllClientsListLock.EnterUpgradeableReadLock();
- try
- {
- int i = AllClients.Count - 1;
- if (i <= clientsPerThread)
- {
- ProcessClients(new ProcessingClientsTask(0, i));
- continue;
- }
- var tasks = new List<ProcessingClientsTask>();
- while (i >= 0)
- {
- var task = new ProcessingClientsTask(i - clientsPerThread + 1, i);
- i -= clientsPerThread;
- tasks.Add(task);
- ThreadPool.QueueUserWorkItem(ProcessClients, task);
- }
- // wait while all tasks is completed
- while (true)
- {
- foreach (ProcessingClientsTask task in tasks)
- {
- if (!task.Completed)
- {
- Thread.Sleep(5);
- continue;
- }
- }
- break;
- }
- }
- catch (Exception e)
- {
- #if DEBUG
- Utils.TraceException(e);
- #endif
- }
- }
- lock (processingLockObj)
- {
- processingThread = null;
- }
- #if DEBUG
- Console.WriteLine("All TCPClients terminated");
- #endif
- }
- #endregion
-
-
-
-
- void BeginReceive()
- {
-
- if (this._disposeCalled || (this._socket == null) || (this._receivedDataKeeper.Length > BufferSize))
- {
- this._needBeginReceive.Restart();
- return;
- }
-
- this._needBeginReceive.Stop();
-
- try
- {
- this._socket.BeginReceive(Chunk, 0, ChunkSize, SocketFlags.None, ReceiveCallback, null);
- }
- catch (Exception e)
- {
- CallOnException(e);
- Dispose();
- }
-
- }
-
-
- void ReceiveCallback(IAsyncResult ar)
- {
- if (this._disposeCalled) return;
- if (ar.IsCompleted)
- {
- var deltaTime = this.LastReceiveTime.ElapsedMilliseconds;
-
- try
- {
- SocketError se;
- int l = this._socket.EndReceive(ar, out se);
- ReceivedBytes += l;
- Interlocked.Add(ref TotalReceivedBytes, l);
- if (se != SocketError.Success) throw new Exception(se.ToString());
- LastReceiveTime.Restart();
- this._lastReceiveDeltaTime = deltaTime;
- this._lastReceiveLength = l;
-
-
- #region Call AsyncOnDataReceived
- if (CallOnReceiveInAsyncMode)
- {
- ThreadPool.QueueUserWorkItem(AsyncOnDataReceived);
- }
- else
- {
- AsyncOnDataReceived(null);
- }
- #endregion
-
- }
- #region catch-dispose
- catch (Exception e)
- {
- #if DEBUG
- Console.Write(" F!ReceiveCallback ");
- Utils.TraceException(e);
- #endif
- CallOnException(e);
- Dispose();
- }
- #endregion
- }
-
- }
- #endregion
-
Ответить
|
Страница: 1 |
Поиск по форуму