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


Полезные ссылки:
user posted image Boost по-русски
user posted image Qt по-русски
Модераторы: archimed7592
  
> Программная реализация диспетчера процессов с использованием системного таймера , Параллельное программирование
    "Написать системную программу - ДИСПЕТЧЕР ПРОЦЕССОВ, осуществляющую функции предоставления процессора в соответствии с выбранной стратегией диспетчеризации готовым к выполнению процессам через определенные кванты времени. Для реализации разделения процессорного времени использовать прерывания системного таймера, по которым через определенные промежутки времени необходимо осуществлять перераспределение процессора следующему готовому процессу. Причем, состояние текущего процесса следует сохранить, с тем, чтобы при следующем предоставлении ему процессорного времени он смог возобновить свою работу именно с этой точки."

    Вот такое задание дали мне по предмету. Как это делать-понятия не имею. Возможно с использованием встроенного ассемблера на Borland C++. Помогите, пожалуйста, если разбираетесь в этом вопросе.
      Это называется планировщик. По какому предмету такое нынче задают? И ещё, именно под UNIX?
      Да и ладно, придумать, написать схему. А в каком вообще виде его надо реализовывать, что бы проверить потом?
      Единственное что тут можно посоветовать - см. сорцы винды NT и юникса.
      Вообще в ядре винды есть KiDispatchInterrupt, которая (боюсь наврать) толи сама планировщик, толи передает управление ещё какой-то Ki ф-ии, которая уже распределяет выполнение между потоками. Кстати, не ПРОЦЕССАМИ, а ПОТОКАМИ, т.к. о процессах там вообще никто ничего не знает:) И ещё инкрементирует всякие счетчики ресурсов процессора. Сохраняется контекст потока и потом восстанавливается. Причем, планирование потоков зависит ещё от IRQL (атрибут работы процессора в момент времени) и ещё всякой разной фигни. Грубо говоря, чем выше irql тем меньше событий могут прервать поток. На >1 - уже не идут прерывания от таймера, поэтому и планирования никакого нет. На последнем прерывания уже не идут вообще. Короче институт клевый у тебя гыгыг
      Сообщение отредактировано: FFF1 -
        Спасибо,конечно,за совет. Но я буду делать попроще и на Windows.
        Написал следующее:
        ExpandedWrap disabled
          #include <stdio.h>
          #include <dos.h>
          #include <conio.h>
          #define INTR 0X1C
          #ifdef __cplusplus
               #define __CPPARGS ...
          #else
               #define __CPPARGS
          #endif
          typedef void _loadds far proc(void);
          struct PCB //process control block-вся информация о процессе
          {PCB *next;unsigned int sp; unsigned int ss;char stack[8096];};
          //???????????????????????????????????
          struct ST_REGS //[B]Точного состава этой структуры я не знаю![/B]
          {unsigned int flags;
          unsigned int cs;
          unsigned int ip;};//возможный состав
          //???????????????????????????????????
          PCB *pcb,*pcb2;
          int count=0;
          //---------------------------------------
          PCB* makepcb(void *proc)//Процедура создания PCB.Где *proc-указатель на функцию
          {
          PCB *pcb;
          ST_REGS far *regs;
          if(pcb=new PCB)
          {
            pcb->ss=FP_SEG(pcb->stack);//сохраняем сегмент стека
            pcb->sp=FP_OFF(pcb->stack)+sizeof(pcb->stack)-sizeof(ST_REGS);//сохраняем смещение стека
            regs=(ST_REGS*)MK_FP(pcb->ss,pcb->sp);//создаём ук-ль на вершину стека,куда будет записана информация о регистрах процесса:
            regs->ip=FP_OFF(proc);//точка входа в процесс
            printf("IP=%u   ",regs->ip);
            regs->cs=FP_SEG(proc);//сегмент
            printf("CS=%u\n",regs->cs);
            regs->flags=_FLAGS;
            return pcb;
          }
          else
          return NULL;
          }
          //---------------------------------------
          void interrupt ( *oldhandler)(__CPPARGS);
          //--------------------------------------
          void interrupt far handler(__CPPARGS)//Диспетчер процессов-таймер
          {
              count++;
              _SS=pcb2->ss;//Пытаемся запустить process2
              _SP=pcb2->sp;
              _BP=_SP;
              oldhandler();
          }
          //-------------------------------------
          void _loadds far process()
          {
           while (count < 18)
              {
                printf("Running process `1");
              }
              return;
          }
          //----------------------------------
          void _loadds far process2()
          {
           while (count < 18)
              {
                printf("Running process `2");
              }
              return;
          }
          //---------------------------------
          void main()
          {
              oldhandler = getvect(INTR);
              setvect(INTR, handler);
              void *pro;
              pro=&process;
              pcb=makepcb(pro);
              pro=&process2;
              pcb2=makepcb(pro);
              process();//Зацикленный process.При срабатывании диспетчера процессов process должен приостановиться и запуститься process2
              setvect(INTR, oldhandler);
              return;
          }

        Для обеспечения параллельной работы процессов будет использоваться прерывание работы процесса по истечению определённого времени с использованием прерывания системного таймера. Реализовано это будет следующим образом: при возникновении прерывания таймера работа текущего процесса прерывается и вызывается диспетчер процессов, который сохраняет данные, которые необходимы процессу для продолжения работы и запускает следующий процесс. Для каждого процесса можно выделить следующие ресурсы: регистры общего назначения, код, глобальные данные, локальные данные и стек. Рассмотрим каждый из ресурсов:
        • в регистрах общего назначения хранятся данные, с которыми процессор работал непосредственно перед прерыванием. Эти Данные различны для каждого процесса, и их необходимо сохранять.
        • код процесса в нашем случае не изменяется, поэтому достаточно лишь знать адрес текущей выполняемой инструкции.
        • глобальные данные при компиляции собираются в один сегмент. В принципе их можно разделить на два сегмента (общий для всех процессов и уникальный для каждого процесса), но это ведёт к усложнению работы с данными и необходимости перезагрузки регистра DS. Поэтому сегмент глобальных данных установим общим для всех процессов, и будем использовать его для обмена данными между процессами.
        • локальные данные и стек. В программах, написанных на языках высокого уровня стек используется для хранения локальных переменных; параметров, передаваемых процедурам; адресов возвратов при вызовах и для хранения многой другой информации. Все эти данные для каждого процесса свои и для правильной работы необходимо предоставить каждому процессу свой стек.
        Чтобы сохранить стек каждого процесса можно поступить следующим образом: каждый раз при прерывании работы процесса сохранять информацию из стека в специально отведённое место и записывать в стек информацию для запускаемого процесса. Но можно сделать иначе. В нашем случае стек представляет собой участок памяти в который информация помещается специальными командами. В этих командах используется адрес вершины стека, хранящийся в регистрах SS, SP. Поэтому мы можем просто выделить для каждого процесса свой стек в виде участка памяти и для каждого процесса записывать в регистры свой адрес. Тогда нам достаточно при запуске процесса выделить ему стек и при прерывании вместо копирования данных просто сохранять содержимое регистров SS, SP. Вернёмся немного назад, к вызову диспетчера процессов. В нашем случае диспетчер процессов представляет собой процедуру обработки прерывания. Для описания таких процедур в языке C++ существует специальное ключевое слово interrupt. При употреблении данного ключевого слова компилятор помещает в начале процедуры код. сохраняющий в стек значения почти всех регистров общего назначения процессора (кроме регистров SS и SP). При прерывании процессор помещает в стек флаги процессора (регистр FLAGS) и адрес следующей инструкции (регистры CS и IP). Получается, что при прерывании процесса в стек поместятся все необходимы нам данные и для написания корректно работающей системы достаточно просто выделить каждому процессу уникальный стек и использовать стандартный обработчик прерываний C++.
        Для хранения информации о процессе в программе будет испольоваться структура :
        ExpandedWrap disabled
          struct PCB
          {PCB *next;unsigned int sp; unsigned int ss;char stack[8096];};

        В качестве процессов можно использовать работу функций.
        Теперь рассмотрим запуск процесса. После того, как система выделила стек процессу, в него (в стек) необходимо поместить все данные аналогично тому, как это происходит при прерывании процесса. Для этого указатель SP необходимо установить не на самый конец стека (не будем забывать, что стек растёт от больших адресов в сторону меньших), а несколько выше и поместить в стек точку входа в процесс и значение регистра флагов процесса. В нашем случае значения для регистров общего назначения в стек можно не помещать (но это не значит, что для них не надо резервировать место), так как в начале
        процедуры компилятор не ожидает ни каких значений в регистрах и будет загружать их сам по мере необходимости.
        Проблема в том,что я не знаю в каком именно порядке и где в стеке сохраняется информация о регистрах IP,CS и регистре флагов. Может кто-нибудь знает?Помогите пожалста!
        1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
        0 пользователей:


        Рейтинг@Mail.ru
        [ Script execution time: 0,0216 ]   [ 15 queries used ]   [ Generated: 21.05.24, 13:51 GMT ]