На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела *nix / gcc / Eclipse / Qt / wxWidgets / GTK+
  • При создании темы ОБЯЗАТЕЛЬНО указывайте версию тулкита / библиотеки / компилятора.
  • Перед тем как задать вопрос, сформулируйте его правильно, чтобы вас могли понять.
  • Нарушение Правил может повлечь наказание со стороны модераторов.


Полезные ссылки:
user posted image Boost по-русски
user posted image Qt по-русски
Модераторы: archimed7592
Страницы: (3) [1] 2 3  все  ( Перейти к последнему сообщению )  
> Fork приложения на сетевом диске
    Хз в тот ли раздел пишу - модеры поправьте, если что.
    Суть такая, есть приложение в виде одного екзешника/бинарника весом под 200Мб. Приложение лежит на сетевом диске откуда и запускается юзверями. Естесно это приводит к тому, что приложение скачивается с сетевого диска. И все бы ничего, да вот только приложение при своей работе активно форкается, а это уже приводит к существенным сетевым нагрузкам и увеличивает время работы.
    Приложение написано на С++/Qt, проблема актуальна как для винды так и для линукса. Есть ли какой-нибудь способ/механизм "объяснить" приложению/системе, что не обязательно при каждом форке качать копию по сети? :-?
      Странно, что она качается.
      Я на сколько знаю, команда fork вызывает копирование процесса в памяти и один процесс пускается по одной ветке, другой по другой.
      При этом, уже обученный до форка процесс является уникальным, поэтому и копируется, полностью, а не запускается новый. Вытягивать его с диска в общем-то не логично. Может что с кодом не так? Он точно после форка содержит память родительского процесса?
      Может просто по ошибке вылетает и перезапускается, вследствие чего и тянет файлик заново..?
        Цитата _lcf_ @
        Есть ли какой-нибудь способ/механизм "объяснить" приложению/системе, что не обязательно при каждом форке качать копию по сети?

        Копируй его на локальный диск перед каждым запуском и все.
        Хотя в линуксе форк не должен тормозить в любом случае. Скорее всего там проблема в чем–то другом.
          Цитата simsergey @
          Странно, что она качается.

          ничего странного так и работает. при форке нужен физический файл.
          Цитата simsergey @
          Может просто по ошибке вылетает и перезапускается, вследствие чего и тянет файлик заново..?

          форк так контролируемый, как раз чтобы снизить негативные последствия возможных падений.
          Цитата Олег М @
          Копируй его на локальный диск перед каждым запуском и все.

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

          Добавлено
          по большому счёту проблема на винде из-за тупого кэша, да...
            Стойте-ка.
            1. А проблема на винде? Именно при форке?
            2. И оправдан ли такой объём бинарника? Может стоит посмотреть в сторону того, чтоб вытащить из него отладочные символы и положить рядышком?
              Цитата negram @
              1. А проблема на винде? Именно при форке?

              ну да, процесс слегка эээ подвисает, пока качает 200 метров по сети, с учетом того, что пользователей могут быть десятки - нагрузка на сеть становится не кислой, так как форкается приложение довольно часто.
              Цитата negram @
              2. И оправдан ли такой объём бинарника?

              политика компании - один екзешник, никаких либ и зависимостей, ноу айти реквест :-? а в последнем релизе туда еще и все мануалы запихали, что увеличило объем в два раза :)
                Хм...
                Вроде бы тема к сетевому программированию никаким боком. :)
                Ну да ладно, попробую свои пять копеек положить на кон...
                Цитата negram @
                1. А проблема на винде? Именно при форке?

                Я что то помню, вроде fork() в винде отсутствует ваще...как класс.
                Аналогом всегда была CreateProcess().
                Цитата _lcf_ @
                Приложение написано на С++/Qt, проблема актуальна как для винды так и для линукса.


                Цитата _lcf_ @
                Естесно это приводит к тому, что приложение скачивается с сетевого диска. И все бы ничего, да вот только приложение при своей работе активно форкается, а это уже приводит к существенным сетевым нагрузкам и увеличивает время работы.

                Интересная постановка проблемы.
                1. Оригинал екзешника лежит на сетевом диске.
                2. Пользователь скачивает экзешник и запускает.
                3. В винде создается процесс и работает автономно. Где то внутри работающего процесса есть код, который должен создать копию этого процесса. CreateProcess это и должен сделать, и обращения к сетевому диску не требуется
                4. В никсах пользователь скачивает экзкшник к себе. Shell оригинальной машины пользователя форкает процесс и таким образом запускает его. Внутри запущенного процесса новая копия создается тем форком, который внутри родительского кода. Никакого обращения к сетевому диску не требуется.
                По логике нигде не нужны повторные обращения к сетевому диску.
                Где ошибка в этих рассуждениях? :(
                M
                Тему все таки перемещу :) Пусть спецы посмотрят
                Сообщение отредактировано: Oleg2004 -
                  Цитата Oleg2004 @
                  Аналогом всегда была CreateProcess

                  А в чем там аналогия?

                  Добавлено
                  Цитата Oleg2004 @
                  Где ошибка в этих рассуждениях?

                  Насколько я понял, пользователь не скачивает exe–шник, а запускает его с удаленнго диска. Немного разные вещи
                    Олег М
                    Цитата _lcf_ @
                    Приложение лежит на сетевом диске откуда и запускается юзверями. Естесно это приводит к тому, что приложение скачивается с сетевого диска.

                    Написано - скачивается...
                    Понятно, что запустить чужое приложение на ЧУЖОЙ машине - это одно.
                    Но ТС ясно пишет - скачивает. :(
                    Вот я и пытаюсь понять, как это ДОЛЖНО!приводить к повышенной сетевой активности.

                    Цитата Олег М @
                    А в чем там аналогия?

                    В создании нового процесса. В винде форка нет, чтобы его создать.
                    Сообщение отредактировано: Oleg2004 -
                      Цитата Oleg2004 @
                      В создании нового процесса. В винде форка нет, чтобы его создать.

                      Никакой аналогии там нет. Fork копирует существующий процесс, CreateProcess создает новый, с нуля. Соответственно, требуется загрузка файла
                        ну говоря скачивается имелось ввиду что в оперативку. файл физически естесно на сетевом диске.
                        ну и да в винде createprocess, а не форк, да и... в линуксе тоже. просто там кеш для сетевых дисков адекватно работает.
                        в общем, пришли к выводу что на винде при первом запуске копировать приложение во временную папку.
                          Короче, дело такое.
                          Код процесса -- выгружаемая память. И выгружается он не в своп, а просто нафиг. Если что, можно снова с exe-шника подгрузить. Так вот, что в линуксе, что в винде возможна ситуация, что форкнутый процесс полезет на диск за кодом. Но если форк честный и проблем с памятью нет, то диск в общем-то не нужен, и странички памяти могут хоть копиорваться, хоть реюзатся до посинения.
                          Другое дело, что насколько я знаю, в винде форк реализован через тот же CreateProcess (поправьте меня). И он всегда загружает образ с диска (ну либо с кеша файловой системы, хотя сомнительно что все 200 метров останутся в этом самом кеше).
                            в винде кэшируется только локальная память, с сетевых источником ничего не кэшируется ибо не гарантируется, что файл не был изменен.
                              Цитата Олег М @
                              Никакой аналогии там нет. Fork копирует существующий процесс, CreateProcess создает новый, с нуля. Соответственно, требуется загрузка файла

                              Проблема в таргеттинге. Т.е. в семантике.
                              Форк не копирует родительский процесс, а разветвляет его с созданием нового процесса.
                              Вот вам простой пример
                              ExpandedWrap disabled
                                /*Тут куча инклюдов, опускаем*/
                                #define MYPORT 3490     /* Порт, на который будет идти соединение*/
                                #define BACKLOG 10 /* Сколько подключений может быть в очереди */
                                int main()
                                   {
                                int sd, newsd; /* Слушаем на сокете sd, новое подключение на сокете newsd */
                                struct sockaddr_in my_addr;/* Серверная адресная информация */
                                struct sockaddr_in their_addr;  /* Адресная информация запрашивающей стороны (клиента) */
                                int sin_size;
                                /* Создаем  Интернет-сокет, ориентированный на соединение*/
                                if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
                                {perror ("socket");exit (1); }
                                my_addr.sin_family = AF_INET;   /* В порядке байтов хоста */
                                my_addr.sin_port = htons (MYPORT);/* short, в порядке байтов сети */
                                /* Авто-заполнение IP-адресом серверного сетевого интерфейса */
                                my_addr.sin_addr.s_addr = INADDR_ANY;
                                bzero(&(my_addr.sin_zero), 8);/* Обнуляем остальную часть struct */
                                /* Связываем только-что созданный сокет с его локальным адресом */
                                if (bind(sd, (struct sockaddr *)&my_addr, sizeof (struct sockaddr)) == -1)
                                {perror ("bind");exit (1);   }
                                /* Организуем очередь прослушивания сети на порту MYPORT */
                                if (listen (sd, BACKLOG) == -1)
                                {perror ("listen");exit (1);}
                                while(1) /* Главный цикл accept()*/
                                {  
                                sin_size = sizeof (struct sockaddr_in);
                                if ((newsd = accept (sd, (struct sockaddr *)&their_addr, &sin_size)) == -1)
                                {  perror ("accept"); continue; /* продолжаем прием*/   }
                                /* Приняли запрос на соединение и принимаем решение ответить на него*/
                                printf (" сервер: Принял соединение от %s\n ", inet_ntoa (their_addr.sin_addr));
                                if(!fork())
                                [B]{/* Мы находимся в дочернем порожденном процессе */
                                close (sd); /* Закрываем дескриптор слушающего сокета, он потомку не нужен */
                                /* Потомок наследует все файловые дескрипторы родителя, а значит, и newsd */
                                /* Теперь таких сокетов два - в каждом процессе по одному */
                                /* Шлем клиенту 14 байтов */
                                if (send(newfd, " Привет, мир! \n", 14, 0) == -1)perror ("send");
                                close(newsd);/* Закрываем сокет newsd  в порожденном процессе */
                                exit (0);/* Завершаем передачу данных из процесса потомка */
                                }   /* Здесь заканчивается текст процесса программы-потомка*/[/B]
                                close (newsd);  /* Закрываем сокет newsd – родитель в нем не нуждается */
                                while (waitpid (-1, NULL, WNOHANG) > 0);    /* Очищаем порожденные процессы */
                                }/*Конец цикла accept()*/
                                return 0;  
                                }/* Завершаем процесс сервера */

                              Так вот, то что болдом - (Блин, болд не работает в срр) это и есть текст программы нового дочернего процесса. И - ВСЕ.
                              С вызова форка одновременно исполняются теперь два процесса одновременно. И говорить о копировании тут смысла нет. Ваще. Просто процесс-потомок наследует большую часть атрибутов своего родителя, и в частности, открытые файлы (порожденный процесс обладает копией дескрипторов файлов, открытых его родителем).
                              Однако порожденный процесс после вызова fork() с помощью функции exec() может запустить совершенно новый исполнимый файл, при этом его предыдущее "родительское" содержание в памяти заменяется текстом нового файла.
                              Так что вопрос в семантике форка. Это - не копирование, а разветвление. Потому и говорим, что Винда и никсы обладают совершенно разными подходами к вопросам запуска новых процессов.
                              Сообщение отредактировано: Oleg2004 -
                                Цитата Oleg2004 @
                                Форк не копирует родительский процесс, а разветвляет его с созданием нового процесса.

                                Что значит разветвляет?
                                Процесс - это исполняемый код и память, ну и какие-то ресурсы, типа хэндлов. Насколько я понимаю, линукс, в fork() ничего этого не копирует, а просто увеличивает счётчики или типа того. Windows так не умеет.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (3) [1] 2 3  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0529 ]   [ 17 queries used ]   [ Generated: 19.04.24, 15:10 GMT ]