From 106bc4c949c27d108f780ed9856246764b6d8bec Mon Sep 17 00:00:00 2001 From: hassiy Date: Mon, 25 Dec 2023 10:33:58 +0300 Subject: [PATCH] Initial commit --- 1/fork/linux/Read_me.txt | 1 + 1/fork/linux/fork1.cpp | 109 ++++++++++ 1/openmp/linux/Read_me.txt | 22 ++ .../linux/zadanie1_Linux_Remastered (1).cpp | 174 ++++++++++++++++ .../zadanie1_Windows_Remastered (1).cpp | 190 ++++++++++++++++++ 1/system/linux/NE TO/SystemLinux11.cpp | 22 ++ 1/system/linux/NE TO/SystemLinux12.cpp | 58 ++++++ 1/system/linux/ParallelNumber1.cpp | 39 ++++ 1/system/linux/ParallelNumber2.cpp | 76 +++++++ 1/system/windows/ParallelNumber1.cpp | 40 ++++ 1/system/windows/ParallelNumber2.cpp | 76 +++++++ 1/threads/linux/thread1.cpp | 106 ++++++++++ 2/fork/linux/README.md | 1 + 2/fork/linux/main.cpp | 71 +++++++ 2/openmp/linux/Read_me.txt | 22 ++ 2/openmp/linux/openmp2linux.cpp | 59 ++++++ 2/openmp/linux/zadanie2.cpp | 60 ++++++ 2/openmp/windows/zadanie2.cpp | 60 ++++++ 2/system/linux/System21.cpp | 29 +++ 2/system/linux/System22.cpp | 47 +++++ 2/system/windows/Parallel21.cpp | 40 ++++ 2/system/windows/Parallel22.cpp | 67 ++++++ 2/threads/linux/thread2.cpp | 80 ++++++++ 3/fork/linux/Read_me.txt | 1 + 3/fork/linux/fork3.cpp | 145 +++++++++++++ 3/openmp/linux/Read_me.txt | 22 ++ 3/openmp/linux/zadanie3.cpp | 72 +++++++ 3/openmp/windows/zadanie3.cpp | 72 +++++++ 3/system/linux/system31.cpp | 24 +++ 3/system/linux/system32.cpp | 62 ++++++ 3/system/windows/Parallel31.cpp | 40 ++++ 3/system/windows/Parallel32.cpp | 77 +++++++ 3/threads/linux/thread3.cpp | 146 ++++++++++++++ 500f.zip | Bin 0 -> 588000 bytes LICENSE | 9 + README.md | 166 +++++++++++++++ pp-lab.pdf | Bin 0 -> 63002 bytes 37 files changed, 2285 insertions(+) create mode 100644 1/fork/linux/Read_me.txt create mode 100644 1/fork/linux/fork1.cpp create mode 100644 1/openmp/linux/Read_me.txt create mode 100644 1/openmp/linux/zadanie1_Linux_Remastered (1).cpp create mode 100644 1/openmp/windows/zadanie1_Windows_Remastered (1).cpp create mode 100644 1/system/linux/NE TO/SystemLinux11.cpp create mode 100644 1/system/linux/NE TO/SystemLinux12.cpp create mode 100644 1/system/linux/ParallelNumber1.cpp create mode 100644 1/system/linux/ParallelNumber2.cpp create mode 100644 1/system/windows/ParallelNumber1.cpp create mode 100644 1/system/windows/ParallelNumber2.cpp create mode 100644 1/threads/linux/thread1.cpp create mode 100644 2/fork/linux/README.md create mode 100644 2/fork/linux/main.cpp create mode 100644 2/openmp/linux/Read_me.txt create mode 100644 2/openmp/linux/openmp2linux.cpp create mode 100644 2/openmp/linux/zadanie2.cpp create mode 100644 2/openmp/windows/zadanie2.cpp create mode 100644 2/system/linux/System21.cpp create mode 100644 2/system/linux/System22.cpp create mode 100644 2/system/windows/Parallel21.cpp create mode 100644 2/system/windows/Parallel22.cpp create mode 100644 2/threads/linux/thread2.cpp create mode 100644 3/fork/linux/Read_me.txt create mode 100644 3/fork/linux/fork3.cpp create mode 100644 3/openmp/linux/Read_me.txt create mode 100644 3/openmp/linux/zadanie3.cpp create mode 100644 3/openmp/windows/zadanie3.cpp create mode 100644 3/system/linux/system31.cpp create mode 100644 3/system/linux/system32.cpp create mode 100644 3/system/windows/Parallel31.cpp create mode 100644 3/system/windows/Parallel32.cpp create mode 100644 3/threads/linux/thread3.cpp create mode 100644 500f.zip create mode 100644 LICENSE create mode 100644 README.md create mode 100644 pp-lab.pdf diff --git a/1/fork/linux/Read_me.txt b/1/fork/linux/Read_me.txt new file mode 100644 index 0000000..5f79c9c --- /dev/null +++ b/1/fork/linux/Read_me.txt @@ -0,0 +1 @@ +❗❗❗в функции main при создании fork после вызова функции (например shame(h, l, vika) нужно прописать команду «std::terminate(); ». Это нужно сделать во всех заданиях c fork. После этого при запуске в консоли будут строки «terminate called without… », но зато программа сама будет завершаться \ No newline at end of file diff --git a/1/fork/linux/fork1.cpp b/1/fork/linux/fork1.cpp new file mode 100644 index 0000000..c978c3e --- /dev/null +++ b/1/fork/linux/fork1.cpp @@ -0,0 +1,109 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + + +int shame(int i, double long h, double long l) //функция для поиска чисел с 3 делителями +{ + ofstream file2; + string path2 = "/home/danila/zadanie1fork/" + to_string(i); //открываем файл, в который будем записывать промежуточные результаты от одного потока + file2.open(path2); + ifstream file3; + string path3 = "/home/danila/zadanie1fork//simples"; //открываем файл с простыми числами + file3.open(path3); + string dasha; + + while (getline(file3, dasha)) //читаем каждую строку из файла с простыми числами + { + int vika = stoi(dasha); //преобразуем string в int + double long katya = pow(vika, 4); //возводим простые числа в 4 степень + + if (katya > h && katya < l) //если эта 4-я степень входит в промежуток, то записываем ее в промежуточные результаты + { + file2 << fixed << katya << endl; + } + } + file2.close(); + file3.close(); + //здесь тоже меняем + if (i == 4) //эта часть нужна только для fork. Здесь тоже нужно поменять 20 на кол-во потоков на вашем компе. Описание этого фрагмента можете посмотреть внизу + { + ofstream result; //опять же для тупеньких, такой путь в линукс системе(вам нужно указать свой) + result.open("/home/danila/zadanie1fork/result"); + for (int j = 1; j <= 20; j++) { + ifstream jedi; + string path = "/home/danila/zadanie1fork/" + to_string(j); //опять же для тупеньких, такой путь в линукс системе(вам нужно указать свой) + jedi.open(path); + string rita; + while (getline(jedi, rita)) + { + result << rita << endl; + } + jedi.close(); + } + result.close(); + } + + return 0; +} + +int main() +{ + setlocale(LC_ALL, "Russian"); + std::cout << "Start proccess!\n"; + ofstream file1; + string path1 = "/home/danila/zadanie1fork/simples";//открываем файл, в который будем записывать простые числа //опять же для тупеньких, такой путь в линукс системе(вам нужно указать свой) + file1.open(path1); + int check = 1; + + for (int i = 2; i <= pow(100000000000, 0.5); i++) //записывем в файл простые числа + { + check = 1; + for (int j = 2; j < i; j++) + { + if (i % j == 0) { + check = 0; + break; + } + } + if (check == 1) { + file1 << i << endl; + } + + } + file1.close(); + + double long first = 10000000000; //здесь вводим верхнюю границу промежутка, в котором будем искать числа с 3 делителями + double long last = 100000000000; //здесь нижнюю + double long dif = (last - first) / 4; //находим, сколько чисел будет обрабатывать один поток (20 - это кол-во потоков на моём ноуте!!! Вам его нужно будет менять!!!!!!) + double long h = first; + double long l = h + dif; + + //начало fork + for (int i = 1; i <= 4; i++) { //здесь тоже нужно заменить 20 на ваше кол-во потоков + pid_t pid = fork(); //создается новый поток + if (pid == 0) //условие подразумевает дочерний процесс + { + shame(i, h, l); // вызов функции для подсчета + + } + + wait(NULL); + h += dif; + l += dif; + + } + return 0; +} + + diff --git a/1/openmp/linux/Read_me.txt b/1/openmp/linux/Read_me.txt new file mode 100644 index 0000000..7ce2ff4 --- /dev/null +++ b/1/openmp/linux/Read_me.txt @@ -0,0 +1,22 @@ +Крч, я очень долго ебался с Линухом и Code::Blocks, ничего не получалось, поэтому я начал всё делать в CLion-е. Значит так, если вам на зачёте попадётся Linux с OpenMP, то земля вам бетоном. А если серьёзно, то нужно установить CLion. Его можно найти либо в центре приложений, если он там есть, либо гуглим, всякие файлики скачиваем и т.д. Ещё раньше перед установкой потребуется компилятор GCC. Его устанавливаем так: + +Пишем в терминале: +sudo dnf install gcc + +Потом, нам понадобится установить сам OpenMP: +sudo dnf install libgomp + +Можно проверить версию: +rpm -q libgomp + +Теперь устанавливаем СиЛьва (там нужно будет зарегаться, выбрать пробную версию и т.д., справитесь, я в вас верю) и создаём c++ проект, туда кидаем код, который нужен. Надо включить OMP в настройках: + +Переходим в "File" -> "Settings" -> "Build, Execution, Deployment" -> "CMake". +В разделе "CMake options" добавляем флаг -fopenmp. Например: + +-DCMAKE_CXX_FLAGS=-fopenmp + +Должно получиться как на фото. И всё, можно стартовать программу. Не так уж и сложно, правда? + +Скриншот сами знаете где... +https://sun9-78.userapi.com/impg/tcHWz_roDo6N5Wd7yhjGC9rgiv8wDbBnbU17fg/MBsNR_tXzSE.jpg?size=680x110&quality=96&sign=e47d0fac6945f51f810d21589e8c53b4&type=album \ No newline at end of file diff --git a/1/openmp/linux/zadanie1_Linux_Remastered (1).cpp b/1/openmp/linux/zadanie1_Linux_Remastered (1).cpp new file mode 100644 index 0000000..28ffbc3 --- /dev/null +++ b/1/openmp/linux/zadanie1_Linux_Remastered (1).cpp @@ -0,0 +1,174 @@ + + +#include +#include +#include +#include +#include + + +bool is_prime(int num) { + if (num <= 1) { + return false; + } + for (int i = 2; i <= sqrt(num); i++) { + if (num % i == 0) { + return false; + } + } + return true; +} + + +int main() { + + + + long long int low_lim = 10000000000LL; // 1 миллиард + long long int up_lim = 100000000000LL; // 100 миллиардов + + + long long int new_low_lim = pow(low_lim, 1.0 / 4.0); + long long int new_up_lim = pow(up_lim, 1.0 / 4.0); + + + std::vector primes; + + +#pragma omp parallel for + + for (long long int i = new_low_lim; i <= new_up_lim; i++) { + long long int number = pow(i, 4); + + +#pragma omp critical + { + + if (number >= low_lim && number <= up_lim && is_prime(i)) { + + primes.push_back(number); + } + } + } + + + std::ofstream output_file("/home/danila/zadanie1openmp.txt"); + + if (output_file.is_open()) { + + for (const auto& prime_power : primes) { + output_file << prime_power << std::endl; + } + + output_file.close(); + std::cout << "Результаты записаны в файл result.txt на рабочем столе." << std::endl; + } + else { + std::cerr << "Ошибка открытия файла для записи." << std::endl; + } + + + return 0; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// Любопытный, да? \ No newline at end of file diff --git a/1/openmp/windows/zadanie1_Windows_Remastered (1).cpp b/1/openmp/windows/zadanie1_Windows_Remastered (1).cpp new file mode 100644 index 0000000..db6bf85 --- /dev/null +++ b/1/openmp/windows/zadanie1_Windows_Remastered (1).cpp @@ -0,0 +1,190 @@ + + +// Так, братиш, перед тем, как начнём разбираться с прелестями OpenMP, его сначала надо включить в настройках. +// Для этого перейди вверху на вкладку "Проект", затем в меню последней строкой будут свойства твоего проекта. *Тык* туда. +// Затем справа в меню выбери "C++". Слева в таблице найди строку "Поддержка Open MP" и напротив в выпадающем меню выбери "Да (/openmp)". + +// Ты крутой. А теперь слушай сюда. + +// Включаем всякую хрень +#include +#include +#include +#include +#include +#include + +// Это - функция проверки числа на "просто(а)ту" числа. Если число простое (ни на что не делится), то она вернёт true +bool is_prime(int num) { + if (num <= 1) { + return false; + } + for (int i = 2; i <= sqrt(num); i++) { + if (num % i == 0) { + return false; + } + } + return true; +} + +// Главная функция. Здесь происходит вся магия. *вжух* +int main() { + // Мы же русские? + setlocale(LC_ALL, "Russian"); + // Короче, для простоты я буду называть это "главным промежутком", где low_lim - начало, а up_lim - конец + long long int low_lim = 1000000000LL; // 1 миллиард + long long int up_lim = 100000000000LL; // 100 миллиардов + + // А вот это - наш маленький промежуток. Он нам нужен, чтобы найти все подходящие простые числа. + // Здесь - new_low_lim - начало, представляющее собой корень четвертой степени из начала нашего главного промежутка, + // а new_up_lim - то же самое, но с концом + long long int new_low_lim = pow(low_lim, 1.0/4.0); + long long int new_up_lim = pow(up_lim, 1.0/4.0); + + // Это вектор, в котором у нас будут простые числа, которые мы будем возводить в 4-ю степень, + // потому что мы же ищем числа с тремя делителями? А простое число в 4-й степени - и есть такое число. Можешь сам проверить + std::vector primes; + + // Ооо, моя любимая часть. Здесь мы говорим OpenMP распараллелить поток. "for" нужен для того, чтобы каждый поток не создавал новый for, + // потому что в таком случае каждый поток просто создаст свой цикл, и все они будут работать независимо +#pragma omp parallel for + // Вот здесь уже будет несколько потоков. Сколько? Я хз, братан, можешь погуглить свои характеристики + // Даже как-то странно быть комментарием внутри потоков. Если они это читают, то печенек им и частоты побольше) + // Короче, здесь мы вводим цикл for, который идет от меньшей границы к большей нашего младшего промежутка + for (long long int i = new_low_lim; i <= new_up_lim; i++) { + long long int number = pow(i, 4); + + // Опа, крч, дойдя до сюда, поток будет "ждать" завершение записи числа другим потоком. + // Это нужно, чтобы не возникало datarace-а (гугл в помощь) +#pragma omp critical + { + // Провер очка того, что старшее число входит в промежуток и младшее - простое число. + // Для проверки на просто(а)ту мы вызываем функцию is_prime (ты же не забыл о ней?) и передаём ей параметр i + if (number >= low_lim && number <= up_lim && is_prime(i)) { + // Коли так, то заталкиваем младшее в наш вектор + primes.push_back(number); + } + } + } + + // Путь к файлу, в который мы записываем числа с тремя делителями. Только измени путь на свой, а то ещё на мой комп ненароком запишешь + std::ofstream output_file("C:\\Users\\ilyas\\Desktop\\result.txt"); + // Если файл открыт,.. + if (output_file.is_open()) { + // ... то все числа из нашего вектора записываем в файл + for (const auto& prime_power : primes) { + output_file << prime_power << std::endl; + } + // Закрываем файл + output_file.close(); + std::cout << "Результаты записаны в файл result.txt на рабочем столе." << std::endl; + } else { + std::cerr << "Ошибка открытия файла для записи." << std::endl; + } + + // Пусть будет + return 0; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// Любопытный, да? \ No newline at end of file diff --git a/1/system/linux/NE TO/SystemLinux11.cpp b/1/system/linux/NE TO/SystemLinux11.cpp new file mode 100644 index 0000000..f4c495a --- /dev/null +++ b/1/system/linux/NE TO/SystemLinux11.cpp @@ -0,0 +1,22 @@ +#include // +#include +#include +#include +#include + + +int main() { + + std::string s = "./system12"; + + + std::string s1 = s + " 104060400 104060402 1&"; + + std::string s2 = s + " 112550880 112550882 2&"; + + const char* cstr1 = s1.c_str(); + const char* cstr2 = s2.c_str(); + std::system(cstr1); + std::system(cstr2); + return 0; +} diff --git a/1/system/linux/NE TO/SystemLinux12.cpp b/1/system/linux/NE TO/SystemLinux12.cpp new file mode 100644 index 0000000..43269de --- /dev/null +++ b/1/system/linux/NE TO/SystemLinux12.cpp @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include + +int begin, end, filey; + + +std::string str; +std::string path = "/home/danila/systemVZ/Dod/"; + + +bool hasFiveDivisors(int num) { + int count = 0; + for (int i = 1; i <= sqrt(num); i++) { + if (num % i == 0) { + count++; + if (num / i != i) { + count++; + } + } + } + return count == 5; +} + +int main(int argc, char* argv[]) { + + std::string numbersWithFiveDivisors; + int count = 0; + + begin = std::atoi(argv[1]); + + end = std::atoi(argv[2]); + + filey = std::atoi(argv[3]); + for (int num = begin; num <= end; num++) { + if (hasFiveDivisors(num)) { + numbersWithFiveDivisors += std::to_string(num) + " "; + count++; + } + } + path += std::to_string(filey) + ".txt"; + std::ofstream fout; + fout.open(path); + if (fout.is_open()) { + + fout << numbersWithFiveDivisors << std::endl; + fout.close(); + } + + + std::cout << "Numbers with three divisors: " << numbersWithFiveDivisors << std::endl; + std::cout << "Total count: " << count << std::endl; + + return 0; +} \ No newline at end of file diff --git a/1/system/linux/ParallelNumber1.cpp b/1/system/linux/ParallelNumber1.cpp new file mode 100644 index 0000000..dced0eb --- /dev/null +++ b/1/system/linux/ParallelNumber1.cpp @@ -0,0 +1,39 @@ +// ParallelNumber1.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы. +// + +#include +#include +#include +#include + + +int main() { + + std::string s = "./system12"; + + std::string s1 = ""; + const char* cstr1; + int add = 225000000; + int border1 = 100000000; + int border2 = border1 + add; + for (int i = 0; i < 4; i++) { + s1 = s + " " + std::to_string(border1) + " " + std::to_string(border2) + " " + std::to_string(i) + "&"; + cstr1 = s1.c_str(); + std::system(cstr1); + border1 = border2; + border2 += add; + } + + return 0; +} + +// Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки" +// Отладка программы: F5 или меню "Отладка" > "Запустить отладку" + +// Советы по началу работы +// 1. В окне обозревателя решений можно добавлять файлы и управлять ими. +// 2. В окне Team Explorer можно подключиться к системе управления версиями. +// 3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения. +// 4. В окне "Список ошибок" можно просматривать ошибки. +// 5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода. +// 6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл. diff --git a/1/system/linux/ParallelNumber2.cpp b/1/system/linux/ParallelNumber2.cpp new file mode 100644 index 0000000..3db0f16 --- /dev/null +++ b/1/system/linux/ParallelNumber2.cpp @@ -0,0 +1,76 @@ +// ParallelNumber2.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы. +// + +#include +#include +#include +#include +#include + +int begin, end, filey; + +//std::string file_num; +std::string str; +std::string path = "/home/danila/systemVZ/Dod/"; +std::vector primes; + + +bool isPrime(int num) { + if (num <= 1) { + return false; + } + for (int p : primes) { + if (num % p == 0) { + return false; + } + } + return true; +} + +int main(int argc, char* argv[]) { + + std::string numbersWithFiveDivisors; + + begin = std::atoi(argv[1]); + + end = std::atoi(argv[2]); + + filey = std::atoi(argv[3]); + + for (int num = 2; num <= 177; num++) { + if (isPrime(num)) { + primes.push_back(num); + } + } + + for (int i = 0; i < primes.size(); i++) { + if (pow(primes[i], 4) > begin && pow(primes[i], 4) < end) { + numbersWithFiveDivisors += std::to_string(pow(primes[i], 4)) + " \n"; + } + } + + path += std::to_string(filey) + ".txt"; + std::ofstream fout; + fout.open(path); + if (fout.is_open()) { + fout << numbersWithFiveDivisors << std::endl; + fout.close(); + } + + + std::cout << "Numbers with three divisors: \n" << numbersWithFiveDivisors << std::endl; + + system("pause"); + return 0; +} + +// Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки" +// Отладка программы: F5 или меню "Отладка" > "Запустить отладку" + +// Советы по началу работы +// 1. В окне обозревателя решений можно добавлять файлы и управлять ими. +// 2. В окне Team Explorer можно подключиться к системе управления версиями. +// 3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения. +// 4. В окне "Список ошибок" можно просматривать ошибки. +// 5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода. +// 6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл. diff --git a/1/system/windows/ParallelNumber1.cpp b/1/system/windows/ParallelNumber1.cpp new file mode 100644 index 0000000..b87c03e --- /dev/null +++ b/1/system/windows/ParallelNumber1.cpp @@ -0,0 +1,40 @@ +// ParallelNumber1.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы. +// + +#include +#include +#include +#include + + +int main() { + + std::string s = "start C:\\Users\\user\\source\\repos\\ParallelNumber2\\x64\\Debug\\ParallelNumber2.exe"; + + std::string s1 = ""; + const char* cstr1; + int add = 225000000; + int border1 = 100000000; + int border2 = border1 + add; + for (int i = 0; i < 4; i++) { + s1 = s + " " + std::to_string(border1) + " " + std::to_string(border2) + " " + std::to_string(i) + " 1 "; + cstr1 = s1.c_str(); + std::system(cstr1); + border1 = border2; + border2 += add; + } + + system("pause"); + return 0; +} + +// Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки" +// Отладка программы: F5 или меню "Отладка" > "Запустить отладку" + +// Советы по началу работы +// 1. В окне обозревателя решений можно добавлять файлы и управлять ими. +// 2. В окне Team Explorer можно подключиться к системе управления версиями. +// 3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения. +// 4. В окне "Список ошибок" можно просматривать ошибки. +// 5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода. +// 6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл. diff --git a/1/system/windows/ParallelNumber2.cpp b/1/system/windows/ParallelNumber2.cpp new file mode 100644 index 0000000..3fb481f --- /dev/null +++ b/1/system/windows/ParallelNumber2.cpp @@ -0,0 +1,76 @@ +// ParallelNumber2.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы. +// + +#include +#include +#include +#include +#include + +int begin, end, filey; + +//std::string file_num; +std::string str; +std::string path = "C:\\Dod\\"; +std::vector primes; + + +bool isPrime(int num) { + if (num <= 1) { + return false; + } + for (int p : primes) { + if (num % p == 0) { + return false; + } + } + return true; +} + +int main(int argc, char* argv[]) { + + std::string numbersWithFiveDivisors; + + begin = std::atoi(argv[1]); + + end = std::atoi(argv[2]); + + filey = std::atoi(argv[3]); + + for (int num = 2; num <= 177; num++) { + if (isPrime(num)) { + primes.push_back(num); + } + } + + for (int i = 0; i < primes.size(); i++) { + if (pow(primes[i], 4) > begin && pow(primes[i], 4) < end) { + numbersWithFiveDivisors += std::to_string(pow(primes[i], 4)) + " \n"; + } + } + + path += std::to_string(filey) + ".txt"; + std::ofstream fout; + fout.open(path); + if (fout.is_open()) { + fout << numbersWithFiveDivisors << std::endl; + fout.close(); + } + + + std::cout << "Numbers with three divisors: \n" << numbersWithFiveDivisors << std::endl; + + system("pause"); + return 0; +} + +// Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки" +// Отладка программы: F5 или меню "Отладка" > "Запустить отладку" + +// Советы по началу работы +// 1. В окне обозревателя решений можно добавлять файлы и управлять ими. +// 2. В окне Team Explorer можно подключиться к системе управления версиями. +// 3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения. +// 4. В окне "Список ошибок" можно просматривать ошибки. +// 5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода. +// 6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл. diff --git a/1/threads/linux/thread1.cpp b/1/threads/linux/thread1.cpp new file mode 100644 index 0000000..ad05cf9 --- /dev/null +++ b/1/threads/linux/thread1.cpp @@ -0,0 +1,106 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + + +int shame(int i, double long h, double long l) //функция для поиска чисел с 3 делителями +{ + ofstream file2; + string path2 = "/home/danila/thread1output/" + to_string(i); //открываем файл, в который будем записывать промежуточные результаты от одного потока + file2.open(path2); + ifstream file3; + string path3 = "/home/danila/thread1output/simples"; //открываем файл с простыми числами + file3.open(path3); + string dasha; + + while (getline(file3, dasha)) //читаем каждую строку из файла с простыми числами + { + int vika = stoi(dasha); //преобразуем string в int + double long katya = pow(vika, 4); //возводим простые числа в 4 степень + + if (katya > h && katya < l) //если эта 4-я степень входит в промежуток, то записываем ее в промежуточные результаты + { + file2 << fixed << katya << endl; + } + } + file2.close(); + file3.close(); + return 0; +} + +int main() +{ + setlocale(LC_ALL, "Russian"); + std::cout << "Start proccess\n"; + ofstream file1; + string path1 = "/home/danila/thread1output/simples";//открываем файл, в который будем записывать простые числа + file1.open(path1); + int check = 1; + + for (int i = 2; i <= pow(100000000000, 0.5); i++) //записывем в файл простые числа + { + check = 1; + for (int j = 2; j < i; j++) + { + if (i%j == 0) { + check = 0; + break; + } + } + if (check == 1) { + file1 << i << endl; + } + + } + file1.close(); + + double long first = 10000000000; //здесь вводим верхнюю границу промежутка, в котором будем искать числа с 3 делителями + double long last = 100000000000; //здесь нижнюю + double long dif = (last - first) / 4; //находим, сколько чисел будет обрабатывать один поток (20 - это кол-во потоков на моём ноуте!!! Вам его нужно будет менять!!!!!!) + double long h = first; + double long l = h + dif; + + + + //начало thread + std::vector th; + for (int i = 1; i <= 4; i++) { //здесь нужно заменить 20 + th.push_back(thread(shame, i, h, l)); //добавление потоков в вектор и вызов функции + h += dif; + l += dif; + //cout << h << " " << l << endl; + } + for (auto& t : th) { //запуск потоков + t.join(); + //cout << thread::get_id << endl; + } + + ofstream result; + result.open("/home/danila/thread1output/result"); //окрываем файл, в котором будет храниться конечный результат + for (int j = 1; j <= 4; j++) { //здесь нужно заменить 20 + ifstream jedi; + string path = "/home/danila/thread1output/" + to_string(j); //открываем файлы сс промежуточными результатами, полученными от каждого потока + jedi.open(path); + string rita; + while (getline(jedi, rita)) + { + result << rita << endl; //переписываем результаты из промежуточных файлов в конечный + } + jedi.close(); + } + result.close(); + //конец thread + + return 0; + +} \ No newline at end of file diff --git a/2/fork/linux/README.md b/2/fork/linux/README.md new file mode 100644 index 0000000..5f79c9c --- /dev/null +++ b/2/fork/linux/README.md @@ -0,0 +1 @@ +❗❗❗в функции main при создании fork после вызова функции (например shame(h, l, vika) нужно прописать команду «std::terminate(); ». Это нужно сделать во всех заданиях c fork. После этого при запуске в консоли будут строки «terminate called without… », но зато программа сама будет завершаться \ No newline at end of file diff --git a/2/fork/linux/main.cpp b/2/fork/linux/main.cpp new file mode 100644 index 0000000..9973f27 --- /dev/null +++ b/2/fork/linux/main.cpp @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +int shame(int h, int l, string searchString) +{ + for (int i = h; i <= l; ++i) { + ofstream file2; + string path2 = "/home/nik/parallel-programming/500f/result" + to_string(i) + ".txt"; //файл с промежуточным результатом для каждого из 500 данных файлов + file2.open(path2); + ifstream file1; + string path1 = "/home/nik/parallel-programming/500f/" + to_string(i) + ".txt"; //500 данных файлов + file1.open(path1); + string line; + int count = 0; + while (getline(file1, line)) { //читаем данный файл по строкам + ++count; + if (line.find(searchString) != std::string::npos) file2 << "Файл " << i << ", строка " << count << endl; //ищем введенное пользователем "слово" в строке. если нашли, записываем его расположениев промежуточные результаты + } + file1.close(); + file2.close(); + } + + //следующий фрагмент кода нужен только для fork. его описание есть внизу + if (l == 500) + { + ofstream result; + result.open("/home/nik/parallel-programming/500f/result.txt"); + for (int i = 1; i <= 500; ++i) { + ifstream jedi; + string path = "/home/nik/parallel-programming/500f/result" + to_string(i) + ".txt"; + jedi.open(path); + string rita; + while (getline(jedi, rita)) + result << rita << endl; + jedi.close(); + } + result.close(); + } + //конец фрагмента для fork + return 0; +} +int main() +{ + setlocale(LC_ALL, "Russian"); + std::cout << "Hello World!\n"; + int h = 1, l = 125; //500 файлов делим на 20 потоков (у вас может быть по-другому) + string searchString; + cout << "Введите строку: "; + cin >> searchString; + //начало fork + for (int i = 1; i <= 4; ++i) { //здесь нужно заменить 20 на ваше кол-во потоков + pid_t pid = fork(); + if (pid == 0) { + shame(h, l, searchString); //вызов функции в дочернем процессе + std::terminate(); + //cout< "Settings" -> "Build, Execution, Deployment" -> "CMake". +В разделе "CMake options" добавляем флаг -fopenmp. Например: + +-DCMAKE_CXX_FLAGS=-fopenmp + +Должно получиться как на фото. И всё, можно стартовать программу. Не так уж и сложно, правда? + +Скриншот сами знаете где... +https://sun9-78.userapi.com/impg/tcHWz_roDo6N5Wd7yhjGC9rgiv8wDbBnbU17fg/MBsNR_tXzSE.jpg?size=680x110&quality=96&sign=e47d0fac6945f51f810d21589e8c53b4&type=album \ No newline at end of file diff --git a/2/openmp/linux/openmp2linux.cpp b/2/openmp/linux/openmp2linux.cpp new file mode 100644 index 0000000..b492f71 --- /dev/null +++ b/2/openmp/linux/openmp2linux.cpp @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include + +using namespace std; + +// Функция поиска файла +string find_file_with_string(const string& directory) { + string filename; + string search_string = "zxcv"; // Строка, которую нужно найти + + // Получение списка файлов в каталоге +#pragma omp parallel + { +#pragma omp for + for (int i = 1; i <= 500; ++i) { + string filedir = directory + '/' + to_string(i) + ".txt"; + + // Поиск строки в файле + ifstream file(filedir); + if (file.is_open()) { + string line; + while (getline(file, line)) { + // line.find(search_string) - здесь мы ищем подстроку search_string в строке line + // Если подстрока не найдена, string::npos обозначает отсутствие позиции в строке. Значит, надо проверять + if (line.find(search_string) != string::npos) { +#pragma omp critical + { + filename = filedir; + } + break; + } + } + file.close(); + } + } + } + + // Возвращение первого найденного файла + if (filename != "") { + return "Файл найден!\n" + filename; + } + else { + return "Файл с искомой строкой не найден."; + } +} + +int main() { + + string directory = "/home/danila/500f/"; // Заменить на реальный путь к каталогу + + string result = find_file_with_string(directory); + + cout << result << endl; + + return 0; +} diff --git a/2/openmp/linux/zadanie2.cpp b/2/openmp/linux/zadanie2.cpp new file mode 100644 index 0000000..fb66b78 --- /dev/null +++ b/2/openmp/linux/zadanie2.cpp @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; + +// Функция поиска файла +string find_file_with_string(const string& directory) { + string filename; + string search_string = "asdf"; // Строка, которую нужно найти + + // Получение списка файлов в каталоге +#pragma omp parallel + { +#pragma omp for + for (int i = 1; i <= 500; ++i) { + string filedir = directory + '\\' + to_string(i) + ".txt"; + + // Поиск строки в файле + ifstream file(filedir); + if (file.is_open()) { + string line; + while (getline(file, line)) { + // line.find(search_string) - здесь мы ищем подстроку search_string в строке line + // Если подстрока не найдена, string::npos обозначает отсутствие позиции в строке. Значит, надо проверять + if (line.find(search_string) != string::npos) { +#pragma omp critical + { + filename = filedir; + } + break; + } + } + file.close(); + } + } + } + + // Возвращение первого найденного файла + if (filename != "") { + return "Файл найден!\n" + filename; + } + else { + return "Файл с искомой строкой не найден."; + } +} + +int main() { + setlocale(LC_ALL, "Russian"); + string directory = "C:\\Users\\ilyas\\Desktop\\500f"; // Заменить на реальный путь к каталогу + + string result = find_file_with_string(directory); + + cout << result << endl; + + return 0; +} diff --git a/2/openmp/windows/zadanie2.cpp b/2/openmp/windows/zadanie2.cpp new file mode 100644 index 0000000..fb66b78 --- /dev/null +++ b/2/openmp/windows/zadanie2.cpp @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; + +// Функция поиска файла +string find_file_with_string(const string& directory) { + string filename; + string search_string = "asdf"; // Строка, которую нужно найти + + // Получение списка файлов в каталоге +#pragma omp parallel + { +#pragma omp for + for (int i = 1; i <= 500; ++i) { + string filedir = directory + '\\' + to_string(i) + ".txt"; + + // Поиск строки в файле + ifstream file(filedir); + if (file.is_open()) { + string line; + while (getline(file, line)) { + // line.find(search_string) - здесь мы ищем подстроку search_string в строке line + // Если подстрока не найдена, string::npos обозначает отсутствие позиции в строке. Значит, надо проверять + if (line.find(search_string) != string::npos) { +#pragma omp critical + { + filename = filedir; + } + break; + } + } + file.close(); + } + } + } + + // Возвращение первого найденного файла + if (filename != "") { + return "Файл найден!\n" + filename; + } + else { + return "Файл с искомой строкой не найден."; + } +} + +int main() { + setlocale(LC_ALL, "Russian"); + string directory = "C:\\Users\\ilyas\\Desktop\\500f"; // Заменить на реальный путь к каталогу + + string result = find_file_with_string(directory); + + cout << result << endl; + + return 0; +} diff --git a/2/system/linux/System21.cpp b/2/system/linux/System21.cpp new file mode 100644 index 0000000..eb4e725 --- /dev/null +++ b/2/system/linux/System21.cpp @@ -0,0 +1,29 @@ +#include +#include +#include +#include + + +int main() { + + std::string s = "./system22"; + std::string s1 = ""; + const char* cstr1; + + for (int i = 0; i < 4; i++) { + if (i == 3) { + s1 = s + " " + std::to_string(i) + " 1& "; + } + else { + s1 = s + " " + std::to_string(i) + " 0& "; + } + cstr1 = s1.c_str(); + std::system(cstr1); + } + + + + + + return 0; +} \ No newline at end of file diff --git a/2/system/linux/System22.cpp b/2/system/linux/System22.cpp new file mode 100644 index 0000000..a868131 --- /dev/null +++ b/2/system/linux/System22.cpp @@ -0,0 +1,47 @@ +#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING +#include +#include +#include +#include +#include +#include +#include +using namespace std; +namespace fs = experimental::filesystem; +bool searchFileForLine(string filePath, string searchString) { + ifstream file(filePath); + string line; + while (getline(file, line)) { + if (line.find(searchString) != string::npos) { + return true; + } + } + return false; +} +int main(int argc, char* argv[]) { + int count = 0; + string directoryPath; + string searchString = "wxyz";; + string found; + int ver = std::atoi(argv[1]) * 125; + int no = 0; + int cborder = 125; + if (std::atoi(argv[2]) == 1) { + cborder = 126; + } + while (count < cborder) { + directoryPath = "/home/danila/500f/" + std::to_string(ver + count) + ".txt"; + if (searchFileForLine(directoryPath, searchString)) { + found = "Found in file:" + directoryPath + "\n"; + cout << found << endl; + no++; + } + + count++; + } + + if (no == 0) { + cout << "Not found" << endl; + } + return 0; +} \ No newline at end of file diff --git a/2/system/windows/Parallel21.cpp b/2/system/windows/Parallel21.cpp new file mode 100644 index 0000000..862f04f --- /dev/null +++ b/2/system/windows/Parallel21.cpp @@ -0,0 +1,40 @@ +#include +#include +#include +#include + + +int main() { + + std::string s = "start C:\\Users\\user\\source\\repos\\Parallel22\\x64\\Debug\\Parallel22.exe"; + std::string s1 = ""; + const char* cstr1; + + for (int i = 0; i < 4; i++) { + if (i == 3) { + s1 = s + " " + std::to_string(i) + " 1 "; + } + else { + s1 = s + " " + std::to_string(i) + " 0 "; + } + cstr1 = s1.c_str(); + std::system(cstr1); + } + + + + + system("pause"); + return 0; +} + +// Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки" +// Отладка программы: F5 или меню "Отладка" > "Запустить отладку" + +// Советы по началу работы +// 1. В окне обозревателя решений можно добавлять файлы и управлять ими. +// 2. В окне Team Explorer можно подключиться к системе управления версиями. +// 3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения. +// 4. В окне "Список ошибок" можно просматривать ошибки. +// 5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода. +// 6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл. diff --git a/2/system/windows/Parallel22.cpp b/2/system/windows/Parallel22.cpp new file mode 100644 index 0000000..27c7304 --- /dev/null +++ b/2/system/windows/Parallel22.cpp @@ -0,0 +1,67 @@ +// Parallel22.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы. +// + +#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +namespace fs = experimental::filesystem; + +bool searchFileForLine(string filePath, string searchString) { + ifstream file(filePath); + string line; + while (getline(file, line)) { + if (line.find(searchString) != string::npos) { + return true; + } + } + return false; +} +int main(int argc, char* argv[]) { + int count = 0; + string directoryPath; + string searchString = "wxyz";; + string found; + int ver = std::atoi(argv[1]) * 125; + int no = 0; + int cborder = 125; + if (std::atoi(argv[2]) == 1) { + cborder = 126; + } + while (count < cborder) { + directoryPath = "C:\\Dod\\Dod1\\" + std::to_string(ver + count) + ".txt"; + if (searchFileForLine(directoryPath, searchString)) { + found = "Found in file:" + directoryPath + "\n"; + cout << found << endl; + no++; + } + + count++; + } + + if (no == 0) { + cout << "Not found" << endl; + } + + + system("pause"); + return 0; +} + +// Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки" +// Отладка программы: F5 или меню "Отладка" > "Запустить отладку" + +// Советы по началу работы +// 1. В окне обозревателя решений можно добавлять файлы и управлять ими. +// 2. В окне Team Explorer можно подключиться к системе управления версиями. +// 3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения. +// 4. В окне "Список ошибок" можно просматривать ошибки. +// 5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода. +// 6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл. diff --git a/2/threads/linux/thread2.cpp b/2/threads/linux/thread2.cpp new file mode 100644 index 0000000..675672a --- /dev/null +++ b/2/threads/linux/thread2.cpp @@ -0,0 +1,80 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +int shame(int h, int l, string vika) +{ + + for (int i = h; i <= l; i++) + { + ofstream file2; + string path2 = "/home/danila/thread2output/500f/result" + to_string(i) + ".txt"; //файл с промежуточным результатом для каждого из 500 данных файлов + file2.open(path2); + ifstream file1; + string path1 = "/home/danila/thread2output/500f/" + to_string(i) + ".txt"; //500 данных файлов + file1.open(path1); + string katya; + + int count = 0; + while (getline(file1, katya)) //читаем данный файл по строкам + { + count += 1; + if (katya.find(vika) != std::string::npos) file2 << "Файл " << i << ", строка " << count << endl; //ищем введенное пользователем "слово" в строке. если нашли, записываем его расположениев промежуточные результаты + } + file1.close(); + file2.close(); + } + return 0; +} + + + +int main() +{ + + setlocale(LC_ALL, "Russian"); + std::cout << "Hello World!\n"; + + int h = 1, l = 125; //500 файлов делим на 20 потоков (у вас может быть по-другому) + string vika; + cout << "Введите строку: "; + cin >> vika; + + std::vector th; + for (int i = 1; i <= 4; i++) { + th.push_back(thread(shame, h, l, vika)); //заполняем вектор thread'ами + h += 125; + l += 125; + //cout « h « " " « l « endl; + } + for (auto& t : th) { //запускаем thread + t.join(); + } + + ofstream result; + result.open("/home/danila/thread2output/500f/result.txt"); //открываем файл, в который запишем конечный результат + for (int i = 1; i <= 500; i++) { + ifstream jedi; + string path = "/home/danila/thread2output/500f/result" + to_string(i) + ".txt"; //файлы с промежуточными результатами + jedi.open(path); + string rita; + while (getline(jedi, rita)) + { + result << rita << endl; //переносим промежуточные результаты в конечный файл + } + jedi.close(); + } + result.close(); + + +} \ No newline at end of file diff --git a/3/fork/linux/Read_me.txt b/3/fork/linux/Read_me.txt new file mode 100644 index 0000000..5f79c9c --- /dev/null +++ b/3/fork/linux/Read_me.txt @@ -0,0 +1 @@ +❗❗❗в функции main при создании fork после вызова функции (например shame(h, l, vika) нужно прописать команду «std::terminate(); ». Это нужно сделать во всех заданиях c fork. После этого при запуске в консоли будут строки «terminate called without… », но зато программа сама будет завершаться \ No newline at end of file diff --git a/3/fork/linux/fork3.cpp b/3/fork/linux/fork3.cpp new file mode 100644 index 0000000..0405550 --- /dev/null +++ b/3/fork/linux/fork3.cpp @@ -0,0 +1,145 @@ + +//в этой программе описаны два метода: fork и thread. Метод thread работает как обычно. Метод fork не завершает выполнение программы, запустите его и подождите некоторое время (зависит от кол-ва потоков, у меня занимает +// около 10 секунд), после этого закройте терминал вручную. Извините, я понимаю, что это странно, но по-другому я не придумал + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +int fire(int i, int h, int l) +{ + setlocale(LC_ALL, "Russian"); + ofstream file2; + string path2 = "/home/mach_vl/Загрузки/500f/result" + to_string(i)+".txt"; //файл с промежуточным результатом для каждых 25 из 500 данных файлов + file2.open(path2); + + for (int x = h; x<=l; x++) + { + ifstream file1; + string path1 = "/home/mach_vl/Загрузки/500f/" + to_string(x) + ".txt"; //500 данных файлов + file1.open(path1); + string ilya; + char sanya; + //cout<> ilya) //читаем файл по словам и считаем их кол-во + { + wordCount++; + } + file1.close(); + + file1.open(path1); + file1.seekg(0, file1.beg); + while(file1 >> sanya) //читаем файл по симолам и считаем их кол-во + { + symbolCount++; + } + + //записываем результаты в файлы с промежуточными результатами + string vanya(to_string(x) + ") Lines: " + to_string(lineCount) + "; words: " + to_string(wordCount) + "; symbols: " + to_string(symbolCount)); + file2 << vanya << endl; + file1.close(); + } + file2.close(); + + + //следующий фрагмент кода нужен только для fork. его описание есть внизу + if (i == 20) + { + ofstream result; + result.open("/home/mach_vl/Загрузки/500f/result.txt"); + for (int i = 1; i <= 20; i++) { + ifstream jedi; + string path = "/home/mach_vl/Загрузки/500f/result" + to_string(i)+".txt"; + jedi.open(path); + string rita; + while (getline(jedi, rita)) + { + result << rita << endl; + } + jedi.close(); + } + result.close(); + } + //конец фрагмента для fork + + return 0; + +} + +int main() +{ + setlocale(LC_ALL, "Russian"); + int x = 25; //500 файлов делим на 20 потоков (у вас может быть по-другому) + int h = 1; + int l = 25; + + //начало thread + //std::vector th; + //for (int i = 1; i <= 20; i++) { + //th.push_back(thread(fire, i, h, l)); //заполняем вектор thread'ами + //h += x; + //l += x; + //} + //for (auto& t : th) { + //t.join(); //запускаем thread + //} + + //ofstream result; + //result.open("/home/mach_vl/Загрузки/500f/result.txt"); //открываем файл, в который запишем конечный результат + //for (int i = 1; i <= 20; i++) { + // ifstream jedi; + // string path = "/home/mach_vl/Загрузки/500f/result" + to_string(i)+".txt"; //файлы с промежуточными результатами + // jedi.open(path); + // string rita; + // while (getline(jedi, rita)) + // { + // result << rita << endl; //переносим промежуточные результаты в конечный файл + // } + // jedi.close(); + //} + //result.close(); + //конец thread + + + //начало fork + for(int i = 1; i<=20; i++) //здесь нужно заменить 20 на ваше кол-во потоков + { + pid_t pid = fork(); + if (pid==0) + { + fire(i, h, l); //вызов функции в дочернем процессе + } + + wait(NULL); + h+=x; + l+=x; + } + //конец fork + + + + + return 0; +} diff --git a/3/openmp/linux/Read_me.txt b/3/openmp/linux/Read_me.txt new file mode 100644 index 0000000..7ce2ff4 --- /dev/null +++ b/3/openmp/linux/Read_me.txt @@ -0,0 +1,22 @@ +Крч, я очень долго ебался с Линухом и Code::Blocks, ничего не получалось, поэтому я начал всё делать в CLion-е. Значит так, если вам на зачёте попадётся Linux с OpenMP, то земля вам бетоном. А если серьёзно, то нужно установить CLion. Его можно найти либо в центре приложений, если он там есть, либо гуглим, всякие файлики скачиваем и т.д. Ещё раньше перед установкой потребуется компилятор GCC. Его устанавливаем так: + +Пишем в терминале: +sudo dnf install gcc + +Потом, нам понадобится установить сам OpenMP: +sudo dnf install libgomp + +Можно проверить версию: +rpm -q libgomp + +Теперь устанавливаем СиЛьва (там нужно будет зарегаться, выбрать пробную версию и т.д., справитесь, я в вас верю) и создаём c++ проект, туда кидаем код, который нужен. Надо включить OMP в настройках: + +Переходим в "File" -> "Settings" -> "Build, Execution, Deployment" -> "CMake". +В разделе "CMake options" добавляем флаг -fopenmp. Например: + +-DCMAKE_CXX_FLAGS=-fopenmp + +Должно получиться как на фото. И всё, можно стартовать программу. Не так уж и сложно, правда? + +Скриншот сами знаете где... +https://sun9-78.userapi.com/impg/tcHWz_roDo6N5Wd7yhjGC9rgiv8wDbBnbU17fg/MBsNR_tXzSE.jpg?size=680x110&quality=96&sign=e47d0fac6945f51f810d21589e8c53b4&type=album \ No newline at end of file diff --git a/3/openmp/linux/zadanie3.cpp b/3/openmp/linux/zadanie3.cpp new file mode 100644 index 0000000..f100689 --- /dev/null +++ b/3/openmp/linux/zadanie3.cpp @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include +#include +using namespace std; + +// Функция для подчёта статистики о файле +void count_stats(const string& filename, int& line_count, int& word_count, int& char_count) { + ifstream file(filename); + if (!file.is_open()) { + cerr << "Ошибка открытия файла: " << filename << endl; + return; + } + + string line; + while (getline(file, line)) { + //конструкция atomic гарантирует атомарный доступ к определенному месту хранения, а не подвергает его возможности одновременного чтения и записи нескольких потоков, + // что может привести к неопределенным значениям. Другими словами, операция выполняется целиком, без возможности прерывания другими потоками. +#pragma omp atomic + ++line_count; + + char_count += line.size(); + + // Подсчет слов + bool in_word = false; + for (char c : line) { + if (isspace(c)) { + in_word = false; + } + else if (!in_word) { + in_word = true; +#pragma omp atomic + ++word_count; + } + } + } + + file.close(); +} + +int main() { + setlocale(LC_ALL, "Russian"); + const string directory_path = "C:\\Users\\ilyas\\Desktop\\500f"; // Замените на путь к вашему каталогу + + +#pragma omp parallel for + for (int i = 0; i <= 500; ++i) {// Обработка файлов с именами 1.txt, 2.txt, ..., 10.txt. Нужно задать число, о скольких файлах мы хотим видеть стату + + string filename = directory_path + "\\" + to_string(i) + ".txt"; + + int line_count = 0; + int word_count = 0; + int char_count = 0; + + count_stats(filename, line_count, word_count, char_count); + + // Вывод результатов +#pragma omp critical + { + cout << "Статистика для файла " << filename << ":" << endl + << " Количество строк: " << line_count << endl + << " Количество слов: " << word_count << endl + << " Количество символов: " << char_count << endl + << "-------------------------" << endl; + } + } + + return 0; +} + diff --git a/3/openmp/windows/zadanie3.cpp b/3/openmp/windows/zadanie3.cpp new file mode 100644 index 0000000..f100689 --- /dev/null +++ b/3/openmp/windows/zadanie3.cpp @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include +#include +using namespace std; + +// Функция для подчёта статистики о файле +void count_stats(const string& filename, int& line_count, int& word_count, int& char_count) { + ifstream file(filename); + if (!file.is_open()) { + cerr << "Ошибка открытия файла: " << filename << endl; + return; + } + + string line; + while (getline(file, line)) { + //конструкция atomic гарантирует атомарный доступ к определенному месту хранения, а не подвергает его возможности одновременного чтения и записи нескольких потоков, + // что может привести к неопределенным значениям. Другими словами, операция выполняется целиком, без возможности прерывания другими потоками. +#pragma omp atomic + ++line_count; + + char_count += line.size(); + + // Подсчет слов + bool in_word = false; + for (char c : line) { + if (isspace(c)) { + in_word = false; + } + else if (!in_word) { + in_word = true; +#pragma omp atomic + ++word_count; + } + } + } + + file.close(); +} + +int main() { + setlocale(LC_ALL, "Russian"); + const string directory_path = "C:\\Users\\ilyas\\Desktop\\500f"; // Замените на путь к вашему каталогу + + +#pragma omp parallel for + for (int i = 0; i <= 500; ++i) {// Обработка файлов с именами 1.txt, 2.txt, ..., 10.txt. Нужно задать число, о скольких файлах мы хотим видеть стату + + string filename = directory_path + "\\" + to_string(i) + ".txt"; + + int line_count = 0; + int word_count = 0; + int char_count = 0; + + count_stats(filename, line_count, word_count, char_count); + + // Вывод результатов +#pragma omp critical + { + cout << "Статистика для файла " << filename << ":" << endl + << " Количество строк: " << line_count << endl + << " Количество слов: " << word_count << endl + << " Количество символов: " << char_count << endl + << "-------------------------" << endl; + } + } + + return 0; +} + diff --git a/3/system/linux/system31.cpp b/3/system/linux/system31.cpp new file mode 100644 index 0000000..16517d7 --- /dev/null +++ b/3/system/linux/system31.cpp @@ -0,0 +1,24 @@ +#include +#include +#include +#include + + +int main() { + + std::string s = "./system32"; + std::string s1 = ""; + const char* cstr1; + + for (int i = 0; i < 4; i++) { + if (i == 3) { + s1 = s + " " + std::to_string(i) + " 1& "; + } + else { + s1 = s + " " + std::to_string(i) + " 0& "; + } + cstr1 = s1.c_str(); + std::system(cstr1); + } + return 0; +} \ No newline at end of file diff --git a/3/system/linux/system32.cpp b/3/system/linux/system32.cpp new file mode 100644 index 0000000..12ff3b4 --- /dev/null +++ b/3/system/linux/system32.cpp @@ -0,0 +1,62 @@ +#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING +#include +#include +#include +#include +#include +using namespace std::experimental::filesystem::v1; + +void countFileStats(const std::string& filePath) { + std::ifstream file(filePath); + if (!file.is_open()) { + std::cerr << "Unable to open file: " << filePath << std::endl; + return; + } + + std::string line; + int lineCount = 0; + int wordCount = 0; + int charCount = 0; + + while (std::getline(file, line)) { + lineCount++; + charCount += line.length(); + + // Count words in the line + bool inWord = false; + for (char c : line) { + if (std::isalpha(c)) { + if (!inWord) { + inWord = true; + wordCount++; + } + } + else { + inWord = false; + } + } + } + + std::cout << "File: " << filePath << std::endl; + std::cout << "Number of lines: " << lineCount << std::endl; + std::cout << "Number of words: " << wordCount << std::endl; + std::cout << "Number of characters: " << charCount << std::endl; + + file.close(); +} + +int main(int argc, char* argv[]) { + int count = 0; + int ver = std::atoi(argv[1]) * 125; + int cborder = 125; + if (std::atoi(argv[2]) == 1) { + cborder = 126; + } + while (count < cborder) { + std::string directoryPath = "/home/danila/500f/" + std::to_string(ver + count) + ".txt"; + countFileStats(directoryPath); + count++; + } + + return 0; +} \ No newline at end of file diff --git a/3/system/windows/Parallel31.cpp b/3/system/windows/Parallel31.cpp new file mode 100644 index 0000000..bfeb869 --- /dev/null +++ b/3/system/windows/Parallel31.cpp @@ -0,0 +1,40 @@ +// Parallel31.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы. +// + +#include +#include +#include +#include + + +int main() { + + std::string s = "start C:\\Users\\user\\source\\repos\\Parallel32\\x64\\Debug\\Parallel32.exe"; + std::string s1 = ""; + const char* cstr1; + + for (int i = 0; i < 4; i++) { + if (i == 3) { + s1 = s + " " + std::to_string(i) + " 1 "; + } + else { + s1 = s + " " + std::to_string(i) + " 0 "; + } + cstr1 = s1.c_str(); + std::system(cstr1); + } + + system("pause"); + return 0; +} + +// Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки" +// Отладка программы: F5 или меню "Отладка" > "Запустить отладку" + +// Советы по началу работы +// 1. В окне обозревателя решений можно добавлять файлы и управлять ими. +// 2. В окне Team Explorer можно подключиться к системе управления версиями. +// 3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения. +// 4. В окне "Список ошибок" можно просматривать ошибки. +// 5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода. +// 6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл. diff --git a/3/system/windows/Parallel32.cpp b/3/system/windows/Parallel32.cpp new file mode 100644 index 0000000..24266df --- /dev/null +++ b/3/system/windows/Parallel32.cpp @@ -0,0 +1,77 @@ +// Parallel32.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы. +// + +#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING +#include +#include +#include +#include +#include +using namespace std::experimental::filesystem::v1; + +void countFileStats(const std::string& filePath) { + std::ifstream file(filePath); + if (!file.is_open()) { + std::cerr << "Unable to open file: " << filePath << std::endl; + return; + } + + std::string line; + int lineCount = 0; + int wordCount = 0; + int charCount = 0; + + while (std::getline(file, line)) { + lineCount++; + charCount += line.length(); + + // Count words in the line + bool inWord = false; + for (char c : line) { + if (std::isalpha(c)) { + if (!inWord) { + inWord = true; + wordCount++; + } + } + else { + inWord = false; + } + } + } + + std::cout << "File: " << filePath << std::endl; + std::cout << "Number of lines: " << lineCount << std::endl; + std::cout << "Number of words: " << wordCount << std::endl; + std::cout << "Number of characters: " << charCount << std::endl; + + file.close(); +} + +int main(int argc, char* argv[]) { + int count = 0; + int ver = std::atoi(argv[1]) * 125; + int cborder = 125; + if (std::atoi(argv[2]) == 1) { + cborder = 126; + } + while (count < cborder) { + std::string directoryPath = "C:\\Dod\\Dod1\\" + std::to_string(ver + count) + ".txt"; + countFileStats(directoryPath); + count++; + } + + system("pause"); + return 0; +} + +// Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки" +// Отладка программы: F5 или меню "Отладка" > "Запустить отладку" + +// Советы по началу работы +// 1. В окне обозревателя решений можно добавлять файлы и управлять ими. +// 2. В окне Team Explorer можно подключиться к системе управления версиями. +// 3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения. +// 4. В окне "Список ошибок" можно просматривать ошибки. +// 5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода. +// 6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл. diff --git a/3/threads/linux/thread3.cpp b/3/threads/linux/thread3.cpp new file mode 100644 index 0000000..3179ac9 --- /dev/null +++ b/3/threads/linux/thread3.cpp @@ -0,0 +1,146 @@ + +//в этой программе описаны два метода: fork и thread. Метод thread работает как обычно. Метод fork не завершает выполнение программы, запустите его и подождите некоторое время (зависит от кол-ва потоков, у меня занимает +// около 10 секунд), после этого закройте терминал вручную. Извините, я понимаю, что это странно, но по-другому я не придумал + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +int fire(int i, int h, int l) +{ + setlocale(LC_ALL, "Russian"); + ofstream file2; + string path2 = "/home/mach_vl/Загрузки/500f/result" + to_string(i)+".txt"; //файл с промежуточным результатом для каждых 25 из 500 данных файлов + file2.open(path2); + + for (int x = h; x<=l; x++) + { + ifstream file1; + string path1 = "/home/mach_vl/Загрузки/500f/" + to_string(x) + ".txt"; //500 данных файлов + file1.open(path1); + string ilya; + char sanya; + //cout<> ilya) //читаем файл по словам и считаем их кол-во + { + wordCount++; + } + file1.close(); + + file1.open(path1); + file1.seekg(0, file1.beg); + while(file1 >> sanya) //читаем файл по симолам и считаем их кол-во + { + symbolCount++; + } + + //записываем результаты в файлы с промежуточными результатами + string vanya(to_string(x) + ") Lines: " + to_string(lineCount) + "; words: " + to_string(wordCount) + "; symbols: " + to_string(symbolCount)); + file2 << vanya << endl; + file1.close(); + } + file2.close(); + + + //следующий фрагмент кода нужен только для fork. его описание есть внизу + /*if (i == 20) + { + ofstream result; + result.open("/home/mach_vl/Загрузки/500f/result.txt"); + for (int i = 1; i <= 20; i++) { + ifstream jedi; + string path = "/home/mach_vl/Загрузки/500f/result" + to_string(i)+".txt"; + jedi.open(path); + string rita; + while (getline(jedi, rita)) + { + result << rita << endl; + } + jedi.close(); + } + result.close(); + }*/ + //конец фрагмента для fork + + return 0; + +} + +int main() +{ + setlocale(LC_ALL, "Russian"); + int x = 25; //500 файлов делим на 20 потоков (у вас может быть по-другому) + int h = 1; + int l = 25; + + //начало thread + std::vector th; + for (int i = 1; i <= 20; i++) { + th.push_back(thread(fire, i, h, l)); //заполняем вектор thread'ами + h += x; + l += x; + } + for (auto& t : th) { + t.join(); //запускаем thread + } + + ofstream result; + result.open("/home/mach_vl/Загрузки/500f/result.txt"); //открываем файл, в который запишем конечный результат + for (int i = 1; i <= 20; i++) { + ifstream jedi; + string path = "/home/mach_vl/Загрузки/500f/result" + to_string(i)+".txt"; //файлы с промежуточными результатами + jedi.open(path); + string rita; + while (getline(jedi, rita)) + { + result << rita << endl; //переносим промежуточные результаты в конечный файл + } + jedi.close(); + } + result.close(); + //конец thread + + + //начало fork + /*for(int i = 1; i<=20; i++) //здесь нужно заменить 20 на ваше кол-во потоков + { + pid_t pid = fork(); + if (pid==0) + { + fire(i, h, l); //вызов функции в дочернем процессе + } + + wait(NULL); + h+=x; + l+=x; + }*/ + //конец fork + + + + + return 0; +} diff --git a/500f.zip b/500f.zip new file mode 100644 index 0000000000000000000000000000000000000000..f3db6d3dc78353c8dc195c35cf09883eb237463e GIT binary patch literal 588000 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 O&yjO-DrhO5BmW;!zRXqt literal 0 HcmV?d00001