next up previous contents
Next: Поддерживаемые системные вызовы Up: Программирование с помощью DIPC Previous: Синхронизация   Contents

Снижение сетевой нагрузки

Известно несколько причин, требующих снизить количество сетевых операций вашего приложения. Одна из них - это, очевидно, производительность, поскольку сетевые операции очень ``дорогостоящие'' в сравнении с локальными. Другая причина связана с некоторыми частными ограничениями кода TCP/IP ядра: за короткое время невозможно сделать слишком много сетевых соединений: через некоторое время ядро выдаст: ``Resource temporarily not available'' и ваше приложение завершится ненормально. Вы столкнетесь с этим, если имеете очень быстрые компьютеры, но не сеть.

Ниже приводятся некоторые рекомендации, которые надо учитывать при программировании DIPC:

  1. Владелец структуры IPC выполняет над ней все операции локально. Поэтому, машину, которая чаще всех использует структуру IPC, лучше сделать ее владельцем. Реализуйте это путем создания процесса на данной машине, который первым создаст структуру посредством xxxget().
  2. Периодические блокировки разделяемой памяти - не лучший выход, особенно если наблюдается ``напряженное'' чередование ``тестирований и установок'' блокировок, что приведет к очень частым пересылкам разделяемой памяти по сети. Однако если периодические проверки в подавляющем числе случаев выражаются как тестирующие, и лишь изредка как установочные, вы можете допустить их применение, а также допустить исключение периодических блокировок с помощью semop().
  3. Работа таких системных вызовов, как неблокирующий semop() (с IPC_NOWAIT) в ``напряженном'' цикле, например, for(;;;) { semop(...); ...}, все равно приведет к большому числу сетевых операций, если она не выполняется на компьютере-владельце. Рекомендуется не применять подобную технику, а если вам все-таки необходимо ее присутствие в приложении, то для улучшения ситуации добавьте некоторую задержку перед каждым соответствующим системным вызовом. Например, sleep(1) приостановит приложение на одну секунду. Для разграничения секундных задержек можно применить системный вызов select() и примерно такой код:
struct timeval tv;

fd_set fd;

for(; ; ;)

{

  /* сначала проверка семафора, затем приостановка */

  check_the_semaphore_and_break_if_needed(...);

  /* замечание: Вы должны выполнить инициализацию

      внутри цикла */

  tv.tv_sec = 0;

  /* ожидание в течение 0.5 секунды = 2 семафора

    за секунду */

  tv.tv_usec = 0.5 * 1000000;

  FD_ZERO(&fd);

  select(FD_SETSIZE, &fd, NULL, NULL, &tv);

}



2004-06-22