ЛАБОРАТОРНАЯ РАБОТА №4 (Метода по выполнению лабораторной работы 4 по СПО), страница 3
Описание файла
Документ из архива "Метода по выполнению лабораторной работы 4 по СПО", который расположен в категории "". Всё это находится в предмете "системное программное обеспечение (спо)" из 6 семестр, которые можно найти в файловом архиве МПУ. Не смотря на прямую связь этого архива с МПУ, его также можно найти и в других разделах. Архив можно найти в разделе "книги и методические указания", в предмете "системное программное обеспечение (спо)" в общих файлах.
Онлайн просмотр документа "ЛАБОРАТОРНАЯ РАБОТА №4"
Текст 3 страницы из документа "ЛАБОРАТОРНАЯ РАБОТА №4"
2.1 #include
main ()
{
printf («Hello world!!!\n»);
return 0;
}
2.2 #include
main()
{
write(1,"Hello world!!!\n", 15);
return 0;
}
-
Нахождение наибольшего общего делителя двух чисел по алгоритму
Евклида. Алгоритм Евклида по нахождению наибольшего общего делителя следующий: пусть есть два числа тип, т > п. Делим m на n, r- остаток от деления. Если остаток от деления равен нулю, то n- наибольший общий делитель. Если n не равен 0, заменяем m на n и n на r. Продолжаем деление, пока r не станет равным 0.
#include
unsigned int m,n,r;
main ()
{
scanf("%u %u", &m, &n);
if (n > m)
{
r=m;
m=n;
n=r;
}
printf ("Наибольший общий делитель %u и %u: ",m,n);
while (1)
{
r=m%n;
if ( r = = 0)
break;
else
{
m=n;
n=r;
}
}
printf ("%u\n",n); r
return 0;
}
4) Работа с аргументами командной строки
#include
#include
#include
main (int argc, char* argv[])
{
if (argc < 3)
{
printf ("Недостаточно параметров\n");
return 0;
}
if (!strcmp(argv[l],argv[2]))
printf ("%s\n",argv[l] );
else
atoi(argv[l]) < atoi(argv[2]) ? printf ("%s%s\n", argv[l], argv[2]) :
printf ("%s "%s \n", argv[2] , argv[l] ) ;
return 0;
}
-
Определение формата файла
#include <stdio.h>
#include
unsigned char szSig[]={'\x7F','\x45','\x4C','\x46'};
unsigned char szBuffer[4];
char szFileName[20];
FILE* hFile;
main ()
{
scanf("%s",szFileName);
hFile=fopen (szFileName, "r");
if (hFile ==NULL)
{
switch(errno)
{
case 2:
printf ("Файл не найден\n");
break;
case 13:
printf ("Нет фоступа к файлу\n") ;
break;
default:
printf ("Неизвестная ошибка\n") ;
}
return 1;
}
fread (szBuffer,1,4,hFile);
if (!memcmp(szSig,szBuffer, 4))
printf("Файл %s является исполняемым файлом формата ELF\n" ,szFileName);
else
printf("Файл %s не является исполняемым файлом формата ELF\n " ,szFileName);
fclose(hFile);
return 0;
}
6) Организация каналов
main ()
{
int fd[2];
pipe (fd); /*в родительском процессе образуем два дескриптора канала */
if (fork()) /* образуем дочерний процесс, у которого будут те же дескрипторы */
{ /* эта часть программы происходит в родительском процессе*/
dup2(fd[1],1); /* заменяем стандартный вывод выводом в канал */
close(fd[1]); /*закрываем дескрипторы канала*/ ,
close(fd[0]); /* теперь весь вывод будет происходить в канал */
exec1("/bin/ls”, ''ls", (char*)0); /* заменяем тело родителя на ls */
} /* отсюда начинает работать дочерний процесс */
dup2(fd[0],0), /* в дочернем процессе все делаем аналогично */
close(fd[0]);
close(fd[1]);
exe1l("/bin/wc", "wc", (char*)0);
}
В отцовском процессе запущен процесс ls. Всю выходную информацию ls загружает в канал (ассоциировали стандартное устройство вывода с каналом). Далее в дочернем запустили процесс wс, у которого стандартное устройство ввода связано с дескриптором чтения из канала. Это означает, что все то, что будет писать ls в свое стандартное устройство вывода, будет поступать на стандартное устройство ввода команды wc.
Для того, чтобы канал работал корректно, и читающий дескриптор получил признак конца файла, должны быть закрыты все пишущие дескрипторы. Если в программе не была бы указана выделенная строка, то процесс, связанный с wс завис, так как в этом случае функция, читающая из канала, не дождется признака конца файла. Она будет ожидать его бесконечно долго. В родительском процессе подчеркнутую строку можно было бы не указывать, т.к. дескриптор закрылся бы при завершении процесса, а в дочернем процессе такая строка нужна.
-
Пример программы "Будильник". Функция alrm инициализирует появление сигнала SIG_ALRM
main ()
{
chars[80];
signal (SIG_ALRM, alrm); /* установка режима связи с событием SIG_ALRM на
функцию alrm */
alarm(5); /* заводим будильник */
printf ("Введите имя \n");
for (;;)
{
printf{"имя:");
if (gets(s,80) != NULL) break;
}
printft ("OK! \n");
}
alrm()
{
printf ("\n жду имя \n");
alarm(5);
signal (SlG_ALRM, alrm);
}
В начале программы устанавливаем реакцию на сигнал SIG_ALRM на функцию alrm, далее заводим будильник, запрашиваем "Введите имя" и ожидаем ввода строки символов. Если ввод строки задерживается, то будет вызвана функция alrm, которая напомнит, что программа "ждет имя", опять заведет будильник и поставит себя на обработку сигнала SIG_ALRM еще раз.
И так будет до тех пор, пока не будет введена строка.
Если в момент выполнения системного вызова возникает событие, связанное с сигналом, то система прерывает выполнение системного вызова и возвращает код ответа, равный "-1". Это можно также проанализировать по функции еггnо.
3.5 Вопросы к защите лабораторной работы
1) Опишите схему компиляции программы.
2) Перечислите форматы исполняемых файлов.
3) Перечислите этапы выполнения программы в операционной системе UNIX.
4) Перечислите основные системные функции для работы с файлами.
5) Перечислите основные интерфейсы для файлового ввода/вывода.
6) Перечислите базовые средства взаимодействия процессов в UNIX.
7) Поясните особенности работы с каналами в UNIX.
-
Почему отложенные вызовы не обрабатываются непосредственно обработчиком прерывания таймера?
-
Как получить данные о сегментах кода, данных и стека?
4 Литература
1) А. Робачевский Операционная система UNIX.-СПб.:BHV-Санкт-Петербург, 2002- 528 с.
-
FreeBSD/ Энциклопедия пользователя: Пер. с англ./ Майкл Эбен, Брайан Таймэн – К.: ООО ТИД ДС, 2002 - 736.
-
Ю. Вахалия UNIX изнутри. – СПб.: Питер, 2003 – 844 с.