8. Написать программу поиска одинаковых по их содержимому файлов в двух каталогов, например, Dir1 и Dir2. Пользователь задаёт имена Dir1 и Dir2. В результате работы программы файлы, имеющиеся в Dir1, сравниваются с файлами в Dir2 по их содержимому. Процедуры сравнения должны запускаться с использованием функции fork() в отдельном процессе для каждой пары сравниваемых файлов. Каждый процесс выводит на экран свой pid, имя файла, число просмотренных байт и результаты сравнения. Число запущенных процессов в любой момент времени не должно превышать N (вводится пользователем).Проверить работу программы для каталога /usr/include/ и любого другого каталога в /homeN=6.
// Читаем содержимое 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); } }
// Читаем содержимое 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);
// Блокируем выполнение программы, пока хотя бы один семафор занят 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; }
# Компилируем и запускаем скрипт 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 с.