Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Миргородская 7сессия / Операционные системы / %D0%9E%D0%A1_%D0%A1%D0%93%D0%A2%D0%A3%20v5

.pdf
Скачиваний:
95
Добавлен:
12.02.2015
Размер:
4.09 Mб
Скачать

struct interv { uint64_t s, f; }; interv *trtime;

void* threadfunc ( void* data ) {

// заблокироваться на барьере, чтоб соскочить с него одновременно pthread_barrier_wait( &bstart );

int id = pthread_self() - 2; trtime[ id ].s = ClockCycles(); workproc( (int)data ); trtime[ id ].f = ClockCycles();

pthread_barrier_wait( &bfinish ); return NULL;

};

int main( int argc, char *argv[] ) {

int opt, val, nthr = 1, nall = SHRT_MAX;

while ( ( opt = getopt( argc, argv, "t:n:p:a:" ) ) != -1 ) { switch( opt ) {

case 't' :

if( sscanf( optarg, "%i", &val ) != 1 ) perror( "parse command line failed" ), exit( EXIT_FAILURE );

if( val > 0 && val <= SHRT_MAX ) nthr = val; break;

case 'p' :

if( sscanf( optarg, "%i", &val ) != 1 ) perror( "parse command line failed" ), exit( EXIT_FAILURE );

if( val != getprio( 0 ) )

if( setprio( 0, val ) == -1 ) perror( "priority isn't a valid" ), exit( EXIT_FAILURE );

break; case 'n' :

if( sscanf( optarg, "%i", &val ) != 1 ) perror( "parse command line failed" ), exit( EXIT_FAILURE );

if( val > 0 ) nsingl *= val; break;

case 'a' :

if( sscanf( optarg, "%i", &val ) != 1 ) perror( "parse command line failed" ), exit( EXIT_FAILURE );

if( val > 0 ) nall = val; break;

default :

perror( "parse command line failed" ), exit( EXIT_FAILURE ); break;

}

};

151

if( nthr > 1 ) cout << "Multi-thread evaluation, thread number = " << nthr; else cout << "Single-thread evaluation";

cout << " , priority level: " << getprio( 0 ) << endl; _clockperiod clcout;

ClockPeriod( CLOCK_REALTIME, NULL, &clcout, 0 );

cout << "rescheduling = \t" << clcout.nsec * 4. / 1000000. << endl;

//калибровка единичного выполнения const int NCALIBR = 512;

uint64_t tmin = 0, tmax = 0; tmin = ClockCycles(); workproc( NCALIBR ); tmax = ClockCycles();

cout << "calculating = \t" << cycle2milisec ( tmax - tmin ) / NCALIBR << endl;

//многопотоковое выполнение

if( pthread_barrier_init( &bstart, NULL, nthr ) != EOK ) perror( "barrier init" ), exit( EXIT_FAILURE );

if( pthread_barrier_init( &bfinish, NULL, nthr + 1 ) != EOK ) perror( "barrier init" ), exit( EXIT_FAILURE );

trtime = new interv [ nthr ]; int cur = 0, prev = 0;

for( int i = 0; i < nthr; i++ ) {

cur = (int)floor( (double)nall / (double)nthr * ( i + 1 ) + .5 ); prev = (int)floor( (double)nall / (double)nthr * i + .5 );

if( pthread_create( NULL, NULL, threadfunc, (void*)( cur - prev ) ) != EOK ) perror( "thread create" ), exit( EXIT_FAILURE );

};

pthread_barrier_wait( &bfinish ); for( int i = 0; i < nthr; i++ ) {

tmin = ( i == 0 ) ? trtime[ 0 ].s : __min( tmin, trtime[ i ].s ); tmax = ( i == 0 ) ? trtime[ 0 ].f : __max( tmax, trtime[ i ].f );

};

cout << "evaluation = \t" << cycle2milisec ( tmax - tmin ) / nall << endl; pthread_barrier_destroy( &bstart );

pthread_barrier_destroy( &bfinish ); delete trtime;

exit( EXIT_SUCCESS );

};

Логика этого приложения крайне проста: есть некоторая продолжи-

тельная по времени рабочая функция (workproc), выполняющая массирован-

ные вычисления. Многократно (это число определяется ключом запуска а)

выполняется рабочая функция. Хорошо (то есть корректнее), если время ее

единичного выполнения, которое задается ключом p. В системе установлена

152

диспетчеризация по умолчанию - круговая, или карусельная). Весь объем этой работы делится поровну (или почти поровну) между несколькими (ключ t) потоками. На рис.53 показано выполнение программы t1.cc в перспективе

System Profiler.

Сравниваем усредненное время единичного выполнения рабочей функ-

ции для разного числа выполняющих потоков (в выводе "calculating" - это время эталонного вычисления в одном главном потоке, a "evaluation" - время того же вычисления, но во многих потоках). Для того чтобы иметь еще боль-

шую гибкость, предоставляется возможность переопределять приоритет, под которым в системе все это происходит (ключ р).

Рис.53. Выполнение программы t1.cc

153

Краткий итог этого теста может звучать так: при достаточно высоком уровне приоритета (выше 12-13, когда на его выполнение не влияют процес-

сы обслуживания клавиатуры, мыши и др.) время выполнения в «классиче-

ском» последовательном коде и в многопоточном коде (где несколько тысяч потоков!) практически не различаются. Различия не более 8%, причем в обе стороны.

Создание нового потока в программном коде осуществляет вызов: int pthread_create( pthread_t* thread,

const pthread_attr_t* attr,

void* (*start_routine)(void* ), void* arg );

где thread - NULL или указатель переменной типа pthread_t, значение которой будет загружено идентификатором созданного потока после успеш-

ного выполнения функции. Далее это значение (это и есть TID) может ис-

пользоваться по тексту программы для идентификации созданного потока, attr – NULL: если это значение NULL, то созданный поток будет иметь набор параметров, устанавливаемых по умолчанию. Если нет, то поток будет соз-

дан с параметрами, установленными в структуре attr. Start_routine - функция типа void* ()( void* ), функция потока; это тот код, который будет фактиче-

ски выполняться в качестве отдельного потока. arg - указатель на блок дан-

ных, передаваемых start.routine в качестве входного параметра. Вместе с од-

ним процессом функционируют и другие потоки процесса. В отличие от соз-

даваемых параллельных процессов, рассмотренных ранее, все потоки, созда-

ваемые в рамках одного процесса, разделяют единое адресное пространство процесса, и поэтому все переменные процесса, находящиеся в области види-

мости любого потока, доступны этому потоку.

154

3.6. Файловые системы QNX

Высокая степень отказоустойчивости благодаря разбиению блоков а основной битовой карте, защита от потерь данных и возможность быстрого восстановления, использование многопоточности, приоритетность. Родной раздел QNX называется QNX4FS (для версий ОС QNX 4.х – 6.3.) и QNX6FS (начиная с версии ОС QNX 6.4.0), новый раздел создается утилитой fdisk [15]. Принято согласование разделов - первое число порядковый номер диска, второе – тип раздела диска. Раздел имеет компоненты: блок загрузки,

ключевой (root), битовая карта, корневой каталог. Блок загрузчика - первич-

ный физический блок в разделе диска. Содержит начальный загрузчик. Кор-

невой блок имеет структуру обычного, содержит следующие в себе: корне-

вой root каталог, файл /.inodes – информационный узел. Если имя файла длиннее 16 символов, содержимое файла помещается в этот файл. Файл

/.boot содержит загрузочный образ ОС. Файл /.altboot - содержит резервный загрузочный образ. Файл /.longfilenames – файл, содержащий столько битов,

сколько разделов у диска. Каждому физическому разделу соответствует 1

бит.

Типы файлов.

В QNX файл - это объект, в который может производиться запись, из которого может производиться чтение, либо и то и другое. QNX поддержива-

ет шесть типов файлов: В QNX поддерживаются следующие типы файлов:

регулярные(обычные) файлы;

каталоги; жёсткие и символические ссылки;

блок- и байт-ориентированные специальные файлы;

специальные именованные устройства (Named Special Device);

именованные программные каналы (pipes).

Регулярные файлы - состоят из последовательности байт с произволь-

ным доступом и не имеют предопределенной структуры. Они составляют

155

большинство файлов в файловых системах. Файловые системы поддержи-

ваются Менеджером файловой системы и реализованы на базе блок-

ориентированных файлов, соответствующих разделам диска.

Каталоги - содержат элементы каталога и информацию, необходимую для поиска регулярных файлов; также содержат статус и атрибуты для каж-

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

вать файл и работать с ним. Файл может быть идентифицирован несколькими именами.

Символические связи (ссылки) - содержат путь к файлу или каталогу, к

которым перенаправляются все запросы; символические связи, часто исполь-

зуются для предоставления множества путей к одному файлу.

Программные каналы (pipes) и FIFO - служат как каналы ввода/вывода между взаимодействующими процессами.

Блок-ориентированные файлы - относятся к устройствам, таким, как диски, ленты и разделы дисков. Доступ к этим файлам обычно осуществля-

ется таким образом, что аппаратные характеристики устройств скрыты от приложений.

Байт-ориентированные специальные файлы-файлы, аналогичные блоч-

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

кой аппаратуре относятся, например, последовательный порт, сетевая карта и т.п. Эти файлы ,так же как и блочные. Создаются драйверами при запуске.

Жесткие ссылки (связи) - дополнительные элементы каталога. При ее создании, во-первых, информация о физическом размещении данных выно-

сится в файл /.inodes, во-вторых, счетчик ссылок (атрибут файла) увеличива-

ется на единицу. При удалении одной из жестких ссылок реально будет уда-

лен только соответствующий элемент каталога, а счетчик ссылок на inode-

запись будет уменьшен на единицу. Как только счетчик достигнет значения

“ноль”, и inode-запись ,и физические данные файла будут уничтожены.

156

Именованные специальные устройства-специальный дополнительный тип файлов (Named Special Device).

В QNX файл может обозначаться более чем одним именем. Каждое имя файла называется связью. В действительности существует два вида связей:

жесткие связи, или просто "связи", и символические связи. Для поддержки связей каждого файла, имя файла отделяется от остальной информации, опи-

сывающей файл. Эта информация хранится в структуре, называемой inode

(индексным дескриптором).

Если файл имеет только одну связь (т.е. одно имя), то блок inode хра-

нится в элементе каталога для этого файла. Но если файл имеет более чем одну связь, то inode хранится как запись в специальном файле /.inodes, а

элемент каталога для файла содержит указатель на запись inode.Можно соз-

дать связь для файла, только если файл исвязь находятся в одной и той же файловой системе.

Нельзя создавать жесткие связи для каталога. Однако каждый каталог имеет две жестко определенные связи: «.» («точка»), «..» («точка точка»).

Имя файла "точка" соответствует текущему каталогу; "точка точка" соответ-

ствует каталогу, предшествующему текущему каталогу.

Доступ к регулярным файлам и каталогам управляется битами режима,

хранящимися в inode (индексном дескрипторе) файла. Эти биты разрешают чтение, запись и выполнение в зависимости от эффективных ID пользователя

игруппы. При этом пользователи делятся на три категории:

владелец файла;

члены группы, к которой принадлежит владелец;

остальные.

Процесс может выполняться с ID пользователя или ID группы файла, а

не родительского процесса. Механизм, который позволяет это, называется setuid (установить ID пользователя) и setgid (установить ID группы).

157

QNX может работать со следующими типами файловых систем:

1) встраиваемые: образная (ROM/Flash, Execute-in-place), в ОЗУ (вре-

менное хранилище), NOR Flash (линейное flash-ППЗУ), NAND Flash (стра-

ничное flash-ППЗУ);

2)дисковые: OC QNX (POSIX (QNX4)), Linux (Ext2), MS-DOS (FAT 12, 16, 32), CD-ROM (ISO9660, Joliet);

3)специальные: со сжатием (разворачивание «на лету»), пакетная (об-

новления и откаты на «лету»);

4) сетевые: NFS (совместимость с UNIX), CIFS ( совместимость Microsoft).

На рис. 54 показана типовая структура каталогов QNX Neutino. Основ-

ные каталоги следующие [5]:

Рис. 54 Организация каталогов QNX Neutino

Корневой каталог "/" является основой любой файловой системы

UNIX. Все остальные файлы и каталоги располагаются в рамках структуры,

158

порожденной корневым каталогом, независимо от их физического местона-

хождения.

/bin В каталоге /bin находятся наиболее часто употребляемые команды

иутилиты системы, как правило, общего пользования.

/dev Каталог /dev содержит специальные файлы устройств, являю-

щиеся интерфейсом доступа к периферийным устройствам.

/etc В этом каталоге находятся системные конфигурационные файлы и многие утилиты администрирования.

/lib В каталоге /lib находятся библиотечные файлы языка С и других языков программирования.

/lost+found Каталог "потерянных" файлов. Программы проверки и вос-

становления файловой системы помещают файлы в каталог /lost+found под системными числовыми именами.

/mnt Стандартный каталог для временного связывания (монтирования)

физических файловых систем к корневой для получения единого дерева ло-

гической файловой системы.

/home Общеупотребительный каталог для размещения домашних ка-

талогов пользователей.

/usr В этом каталоге находятся подкаталоги различных сервисных под-

систем -системы печати, электронной почты и т. д. (/usr/spool), исполняемые файлы утилит UNIX (/usr/bin), дополнительные программы, используемые на данном компьютере (/usr/Iocal), файлы заголовков (/usr/include), электрон-

ные справочники (/usr/man)n т. д.

/var В UNIX System V этот каталог является заменителем каталога

/usr/spool, используемого для хранения временных файлов различных сер-

висных подсистем — системы печати, электронной почты и т. д.

-/tmp Каталог хранения временных файлов, необходимых для работы различных подсистем QNX.

159

3.7. Инсталляция и последовательность загрузки QNX

Последовательность начального запуска

Как и большинство операционных систем, ОСРВ QNX Neutrino имеет несколько этапов загрузки (рис. 55).

Рис. 55. Процесс начальной загрузки QNX Neutrino

Ниже следует краткое описание каждого этапа [20].

ФАП (фазовая автоподстройка, phased locked loop, PLL). ФАП – это

процесс, длящийся от подачи питания на процессор до начала выполнения процессором первой инструкции. Для большинства ЦПУ процесс ФАП зани-

мает время, за которое исходная тактовая частота задающего генератора про-

ходит через все таймеры, используемые кристаллом. Время, занимаемое про-

цессом ФАП для получения необходимых частот, обычно соответствует наи-

большей временной метке, требуемой для запуска процессора. Время этапа ФАП не зависит от загружаемой ОС и меняется в зависимости от типа ЦПУ.

В некоторых случаях это время может быть более 32 мс.

НЗ (начальный загрузчик, initial program loader, IPL). IPL находит загрузочный образ ОС (OS image - это не ядро) и отдает управление про-

грамме загрузки, которая находится в этом образе. В QNX используется стан-

дартный начальный загрузчик, который выполняет минимально необходи-

мые операции для подготовки памяти, инициализации выбора нужных мик-

росхем и конфигурирования других, необходимых для работы ЦПУ устано-

вок. После окончания этих установок начальный загрузчик копирует в ОЗУ

160