bsuir.info
БГУИР: Дистанционное и заочное обучение
(файловый архив)
Вход (быстрый)
Регистрация
Категории каталога
Другое [197]
Бухучет [16]
ВМиМОвЭ [4]
ОДМиТА [13]
ОЛОБД [17]
ООПиП [67]
ОС [19]
ПСОД [47]
Форма входа
Поиск
Статистика

Онлайн всего: 8
Гостей: 8
Пользователей: 0
Файловый архив
Файлы » ИСиТвЭ » ОС

Контрольная по ОС (вариант 8)
Подробности о скачивании 13.02.2012, 20:28
8. Написать программу поиска одинаковых по их содержимому файлов в двух каталогов, например, Dir1 и Dir2. Пользователь задаёт имена Dir1 и Dir2. В результате работы программы файлы, имеющиеся в Dir1, сравниваются с файлами в Dir2 по их содержимому. Процедуры сравнения должны запускаться с использованием функции fork() в отдельном процессе для каждой пары сравниваемых файлов. Каждый процесс выводит на экран свой pid, имя файла, число просмотренных байт и результаты сравнения. Число запущенных процессов в любой момент времени не должно превышать N (вводится пользователем).Проверить работу программы для каталога /usr/include/ и любого другого каталога в /homeN=6.

Программный код
#include <iostream>
#include <string>
#include <vector>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <semaphore.h>
#include <fstream>

using namespace std;

void compareFiles(string, string);
sem_t *semaphore;

int main()
{
string sDir1, sDir2;
unsigned int nProcess;

// Вводим входные данные

cout<<"Enter 1-th dir: ";
cin>>sDir1;
cout<<"Enter 2-th dir: ";
cin>>sDir2;
cout<<"Enter max process count: ";
cin>>nProcess;

// Создаем семафор
semaphore = sem_open("/search.0", O_CREAT, S_IRWXU, nProcess);

vector<string> aFiles1, aFiles2;
DIR *phDir;

// Открываем каталог 1 для чтения файлов
if((phDir = opendir(sDir1.c_str())) == NULL) {
cerr<<"Error("<<errno<<") opening "<<sDir1<<endl;
return errno;
}

// Читаем содержимое 1го каталога
struct dirent *pDirInner;
struct stat statv;

while ((pDirInner = readdir(phDir)) != NULL) {
// Составляем полное имя файла
string sFileName(sDir1);
sFileName += "/";
sFileName += pDirInner->d_name;

// Получаем информацию о файле
if (stat(sFileName.c_str(), &statv) == -1) {
cerr<<"Error getting file info '"<<sFileName.c_str()<<"'"<<endl;
return -1;
}

// Если найденный элемент файл, добавляем его в массив для сравнения
if ((statv.st_mode & S_IFMT) == S_IFREG) {
aFiles1.push_back(sFileName);
}
}

// Закрываем 1ый каталог
closedir(phDir);

// Открываем каталог 2 для чтения файлов
if((phDir = opendir(sDir2.c_str())) == NULL) {
cerr<<"Error("<<errno<<") opening "<<sDir2<<endl;
return errno;
}

// Читаем содержимое 2го каталога
while ((pDirInner = readdir(phDir)) != NULL) {
// Составляем полное имя файла
string sFileName(sDir2);
sFileName += "/";
sFileName += pDirInner->d_name;

// Получаем информацию о файле
if (stat(sFileName.c_str(), &statv) == -1) {
cerr<<"Error getting file info '"<<sFileName.c_str()<<"'"<<endl;
return -1;
}

// Если найденный элемент файл, добавляем его в массив для сравнения
if ((statv.st_mode & S_IFMT) == S_IFREG) {
aFiles2.push_back(sFileName);
}
}

// Закрываем 2ый каталог
closedir(phDir);

// Запускаем цикл сравнивания всех файлов 2х каталогов друг с другом
for (unsigned int i = 0; i < aFiles1.size(); i++) {
for (unsigned int j = 0; j < aFiles2.size(); j++) {
// Блокируем выполение программы, пока все семафоры заняты
int iSemValue;
do { sem_getvalue(semaphore, &iSemValue); } while (!iSemValue);

// Сравниваем 2 файла
compareFiles(aFiles1[i], aFiles2[j]);
}
}

// Блокируем выполнение программы, пока хотя бы один семафор занят
int iSemValue;
do { sem_getvalue(semaphore, &iSemValue); } while (iSemValue != nProcess);

// Уничтожаем семафор
sem_unlink("/search.0");

return 0;
}

void compareFiles(string sFile1, string sFile2)
{
// Создание нового процесса
pid_t pid;
pid = fork();

// Если произошла ошибка - выходим из процесса
if (pid == (pid_t)-1) {
cerr<<"Error during creation process"<<endl;
return;
}

// Если новый процесс создан успешно - начинаем сравнивать файлы
if (pid == (pid_t)0) {
// Занимаем один семафор
sem_wait(semaphore);

cout<<"Process "<<getpid()<<": started"<<endl;
cout<<"Process "<<getpid()<<": compare '"<<sFile1<<"' with '"<<sFile2<<"'"<<endl;

// Получаем размеры 2х файлов
struct stat stat1, stat2;
stat(sFile1.c_str(), &stat1);
stat(sFile2.c_str(), &stat2);

if (stat1.st_size != stat2.st_size) {
cout<<"Process "<<getpid()<<": files '"<<sFile1<<"'("<<stat1.st_size<<" bytes) and '"<<sFile2<<"'("<<stat2.st_size<<" bytes) are not equal"<<endl;
} else {
fstream sfile1(sFile1.c_str(), fstream::in);
fstream sfile2(sFile2.c_str(), fstream::in);

char ch1, ch2;
while (!sfile1.eof() && !sfile2.eof()) {
sfile1.get(ch1);
sfile2.get(ch2);

if (ch1 != ch2 && !sfile1.eof() && !sfile2.eof()) {
cout<<"Process "<<getpid()<<": files '"<<sFile1<<"'("<<stat1.st_size<<" bytes) and '"<<sFile2<<"'("<<stat2.st_size<<" bytes) are not equal"<<endl;
break;
}
}

if (sfile1.eof() && sfile2.eof()) {
cout<<"Process "<<getpid()<<": files '"<<sFile1<<"'("<<stat1.st_size<<" bytes) and '"<<sFile2<<"'("<<stat2.st_size<<" bytes) are equal"<<endl;
}

sfile1.close();
sfile2.close();
}

cout<<"Process "<<getpid()<<": done"<<endl;
// Освобождаем семафор
sem_post(semaphore);
// Завершаем процесс
_exit(0);
}
}

Результат выполнения программы

# Компилируем и запускаем скрипт
nik@virtual:~$ make && ./search
g++ -lpthread main.cpp -o search

# Вводим исходные данные
Enter 1-th dir: /tmp/f1
Enter 2-th dir: /tmp/f2
Enter max process count: 3

# Результат работы скрипта
Process 2150: started
Process 2150: compare '/tmp/f1/test1.php' with '/tmp/f2/test1.php'
Process 2150: files '/tmp/f1/test1.php'(3 bytes) and '/tmp/f2/test1.php'(3 bytes) are equal
Process 2150: done
Process 2151: started
Process 2151: compare '/tmp/f1/test1.php' with '/tmp/f2/2.txt'
Process 2151: files '/tmp/f1/test1.php'(3 bytes) and '/tmp/f2/2.txt'(8031766 bytes) are not equal
Process 2151: done
Process 2152: started
Process 2152: compare '/tmp/f1/test1.php' with '/tmp/f2/1.txt'
Process 2152: files '/tmp/f1/test1.php'(3 bytes) and '/tmp/f2/1.txt'(8031766 bytes) are not equal
Process 2152: done
Process 2153: started
Process 2153: compare '/tmp/f1/2.txt' with '/tmp/f2/test1.php'
Process 2153: files '/tmp/f1/2.txt'(8031766 bytes) and '/tmp/f2/test1.php'(3 bytes) are not equal
Process 2153: done
Process 2154: started
Process 2154: compare '/tmp/f1/2.txt' with '/tmp/f2/2.txt'
Process 2155: started
Process 2155: compare '/tmp/f1/2.txt' with '/tmp/f2/1.txt'
Process 2156: started
Process 2156: compare '/tmp/f1/1.txt' with '/tmp/f2/test1.php'
Process 2156: files '/tmp/f1/1.txt'(8031766 bytes) and '/tmp/f2/test1.php'(3 bytes) are not equal
Process 2156: done
Process 2157: started
Process 2157: compare '/tmp/f1/1.txt' with '/tmp/f2/2.txt'
Process 2154: files '/tmp/f1/2.txt'(8031766 bytes) and '/tmp/f2/2.txt'(8031766 bytes) are equal
Process 2154: done
Process 2158: started
Process 2158: compare '/tmp/f1/1.txt' with '/tmp/f2/1.txt'
Process 2155: files '/tmp/f1/2.txt'(8031766 bytes) and '/tmp/f2/1.txt'(8031766 bytes) are equal
Process 2155: done
Process 2157: files '/tmp/f1/1.txt'(8031766 bytes) and '/tmp/f2/2.txt'(8031766 bytes) are equal
Process 2157: done
Process 2158: files '/tmp/f1/1.txt'(8031766 bytes) and '/tmp/f2/1.txt'(8031766 bytes) are equal
Process 2158: done

Литература
1. Таненбаум, Э. Современные опреационные системы / Э.Таненбаум. – 2-е изд. – СПб.: Питер, 2002-1040 с.
2. Столингс, В. Операционные системы / В.Столингс. – 3-е изд. – М.: Вильямс, 2002. – 848 с.
3. Олифер, В.Г. Сетевые операционные системы: учеб. /В.Г.Олифер, Н.А. Олифер. – СПб.: Питер, 2001.-544 с.
4. Робачевский, А.М, Операционная система Unix / А.М,Робачевский. – СПб.: BHV – Санкт-Петергбург, 1997.- 528 с.
Категория: ОС | Добавил: Tanik_nik
Просмотров: 2339 | Загрузок: 47
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]