Initial commit

This commit is contained in:
hassiy 2023-12-25 10:33:58 +03:00
commit 106bc4c949
37 changed files with 2285 additions and 0 deletions

1
1/fork/linux/Read_me.txt Normal file
View File

@ -0,0 +1 @@
❗❗❗в функции main при создании fork после вызова функции (например shame(h, l, vika) нужно прописать команду «std::terminate(); ». Это нужно сделать во всех заданиях c fork. После этого при запуске в консоли будут строки «terminate called without… », но зато программа сама будет завершаться

109
1/fork/linux/fork1.cpp Normal file
View File

@ -0,0 +1,109 @@
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <vector>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
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;
}

View File

@ -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

View File

@ -0,0 +1,174 @@

#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <omp.h>
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<long long int> 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;
}
// Любопытный, да?

View File

@ -0,0 +1,190 @@

// Так, братиш, перед тем, как начнём разбираться с прелестями OpenMP, его сначала надо включить в настройках.
// Для этого перейди вверху на вкладку "Проект", затем в меню последней строкой будут свойства твоего проекта. *Тык* туда.
// Затем справа в меню выбери "C++". Слева в таблице найди строку "Поддержка Open MP" и напротив в выпадающем меню выбери "Да (/openmp)".
// Ты крутой. А теперь слушай сюда.
// Включаем всякую хрень
#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#include <omp.h>
#include <locale>
// Это - функция проверки числа на "просто(а)ту" числа. Если число простое (ни на что не делится), то она вернёт 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<long long int> 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;
}
// Любопытный, да?

View File

@ -0,0 +1,22 @@
#include <iostream> //Äëÿ òóïûõ ýòî ñèñòåì äëÿ ëèíóêñà
#include <string>
#include <cmath>
#include <fstream>
#include <stdlib.h>
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;
}

View File

@ -0,0 +1,58 @@
#include <iostream>
#include <string>
#include <cmath>
#include <fstream>
#include <vector>
#include <stdlib.h>
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;
}

View File

@ -0,0 +1,39 @@
// ParallelNumber1.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
//
#include <iostream>
#include <string>
#include <cmath>
#include <fstream>
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-файл.

View File

@ -0,0 +1,76 @@
// ParallelNumber2.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
//
#include <iostream>
#include <string>
#include <cmath>
#include <fstream>
#include <vector>
int begin, end, filey;
//std::string file_num;
std::string str;
std::string path = "/home/danila/systemVZ/Dod/";
std::vector<int> 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-файл.

View File

@ -0,0 +1,40 @@
// ParallelNumber1.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
//
#include <iostream>
#include <string>
#include <cmath>
#include <fstream>
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-файл.

View File

@ -0,0 +1,76 @@
// ParallelNumber2.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
//
#include <iostream>
#include <string>
#include <cmath>
#include <fstream>
#include <vector>
int begin, end, filey;
//std::string file_num;
std::string str;
std::string path = "C:\\Dod\\";
std::vector<int> 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-файл.

106
1/threads/linux/thread1.cpp Normal file
View File

@ -0,0 +1,106 @@
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <vector>
#include <thread>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
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<std::thread> 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;
}

1
2/fork/linux/README.md Normal file
View File

@ -0,0 +1 @@
❗❗❗в функции main при создании fork после вызова функции (например shame(h, l, vika) нужно прописать команду «std::terminate(); ». Это нужно сделать во всех заданиях c fork. После этого при запуске в консоли будут строки «terminate called without… », но зато программа сама будет завершаться

71
2/fork/linux/main.cpp Normal file
View File

@ -0,0 +1,71 @@
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <vector>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
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<<i<<endl;
}
wait(NULL);
h += 25;
l += 125;
}
return 0;
}

View File

@ -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

View File

@ -0,0 +1,59 @@
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <omp.h>
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;
}

View File

@ -0,0 +1,60 @@
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <omp.h>
#include <locale>
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;
}

View File

@ -0,0 +1,60 @@
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <omp.h>
#include <locale>
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;
}

View File

@ -0,0 +1,29 @@
#include <iostream>
#include <string>
#include <cmath>
#include <fstream>
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;
}

View File

@ -0,0 +1,47 @@
#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <filesystem>
#include <experimental/filesystem>
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;
}

View File

@ -0,0 +1,40 @@
#include <iostream>
#include <string>
#include <cmath>
#include <fstream>
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-файл.

View File

@ -0,0 +1,67 @@
// Parallel22.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
//
#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <filesystem>
#include <experimental/filesystem>
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-файл.

View File

@ -0,0 +1,80 @@
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <vector>
#include <thread>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
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<std::thread> 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();
}

1
3/fork/linux/Read_me.txt Normal file
View File

@ -0,0 +1 @@
❗❗❗в функции main при создании fork после вызова функции (например shame(h, l, vika) нужно прописать команду «std::terminate(); ». Это нужно сделать во всех заданиях c fork. После этого при запуске в консоли будут строки «terminate called without… », но зато программа сама будет завершаться

145
3/fork/linux/fork3.cpp Normal file
View File

@ -0,0 +1,145 @@
//в этой программе описаны два метода: fork и thread. Метод thread работает как обычно. Метод fork не завершает выполнение программы, запустите его и подождите некоторое время (зависит от кол-ва потоков, у меня занимает
// около 10 секунд), после этого закройте терминал вручную. Извините, я понимаю, что это странно, но по-другому я не придумал
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <vector>
#include <thread>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
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<<x<<endl;
int lineCount = 0;
int wordCount = 0;
int symbolCount = 0;
while(getline(file1, ilya)) //читаем файл по строкам и считаем их кол-во
{
lineCount++;
}
file1.close();
file1.open(path1);
file1.seekg(0, file1.beg);
while(file1 >> 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<std::thread> 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;
}

View File

@ -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

View File

@ -0,0 +1,72 @@
#include <iostream>
#include <fstream>
#include <vector>
#include <omp.h>
#include <sstream>
#include <locale>
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;
}

View File

@ -0,0 +1,72 @@
#include <iostream>
#include <fstream>
#include <vector>
#include <omp.h>
#include <sstream>
#include <locale>
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;
}

View File

@ -0,0 +1,24 @@
#include <iostream>
#include <string>
#include <cmath>
#include <fstream>
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;
}

View File

@ -0,0 +1,62 @@
#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
#include <iostream>
#include <fstream>
#include <string>
#include <filesystem>
#include <experimental/filesystem>
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;
}

View File

@ -0,0 +1,40 @@
// Parallel31.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
//
#include <iostream>
#include <string>
#include <cmath>
#include <fstream>
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-файл.

View File

@ -0,0 +1,77 @@
// Parallel32.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
//
#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
#include <iostream>
#include <fstream>
#include <string>
#include <filesystem>
#include <experimental/filesystem>
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-файл.

146
3/threads/linux/thread3.cpp Normal file
View File

@ -0,0 +1,146 @@
//в этой программе описаны два метода: fork и thread. Метод thread работает как обычно. Метод fork не завершает выполнение программы, запустите его и подождите некоторое время (зависит от кол-ва потоков, у меня занимает
// около 10 секунд), после этого закройте терминал вручную. Извините, я понимаю, что это странно, но по-другому я не придумал
#include <iostream>
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <vector>
#include <thread>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
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<<x<<endl;
int lineCount = 0;
int wordCount = 0;
int symbolCount = 0;
while(getline(file1, ilya)) //читаем файл по строкам и считаем их кол-во
{
lineCount++;
}
file1.close();
file1.open(path1);
file1.seekg(0, file1.beg);
while(file1 >> 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<std::thread> 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;
}

BIN
500f.zip Normal file

Binary file not shown.

9
LICENSE Normal file
View File

@ -0,0 +1,9 @@
MIT License
Copyright (c) 2023 hassiy
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

166
README.md Normal file
View File

@ -0,0 +1,166 @@
# parallel-programming
A collection of tasks for studying parallel programming
#### 1. Setup a proxy (on university computers only):
##### On Ubuntu:
```sh
echo 'http_proxy="http://212.192.128.4:8080/"' | sudo tee -a /etc/profile
echo 'https_proxy="http://212.192.128.4:8080/"' | sudo tee -a /etc/profile
```
Reboot a virtual machine to apply changes:
```sh
systemctl reboot
```
##### On Fedora:
```sh
echo 'proxy=212.192.128.4:8080' | sudo tee -a /etc/dnf/dnf.conf
echo 'http_proxy="http://212.192.128.4:8080/"' | sudo tee -a /etc/profile
echo 'http_proxy="http://212.192.128.4:8080/"' | sudo tee -a /etc/profile
```
Reboot a virtual machine to apply changes:
```sh
systemctl reboot
```
#### 2. Install a necessary dependencies:
##### On Ubuntu:
```sh
sudo apt install gcc g++ libomp-dev git
```
##### On Fedora:
```sh
sudo dnf install gcc gcc-c++ libgomp git
```
#### 3. Clone the repository:
```sh
git clone https://git.disroot.org/hassiy/parallel-programming.git
```
#### 4. Navigate to the project directory:
```
cd parallel-programming
```
#### 5. Unzip the 500f.zip file:
```sh
unzip 500f.zip
```
#### 6. Use "cd" and "ls" commands to navigate to the necessary variant:
In case to navigate to the 9th variant use command below:
```sh
cd ~/parallel-programming/2/fork/linux
```
#### 7. Inspect README.md file before do something
```sh
less README.md
```
#### 8. (Recommended) Make a backup of a code:
```sh
cp main.cpp main.bk.cpp
```
where "main.cpp" may be different filename (i.e. fork2.cpp)
use "ls" command to check a content of the current directory
#### 9. Edit the code:
To get a count of an available (logical) threads use command below:
```sh
nproc
```
To get username enter command below:
```sh
whoami
```
or
```sh
echo $USER
```
Edit the code using one of "nano", "vi", "vim" text editor:
i.e. using nano:
```sh
nano main.cpp
```
or another .cpp filename. Use "ls" command to verify it
Inspect the comments
###### !Don't forget to change file paths to the proper values!
Save changes and exit
#### 10. Compile a program:
```sh
g++ main.cpp
```
file "a.out" will appear in the current directory
"a.out" is a default binary name in gcc or g++ compilers
Use -o (or --output) option to change an executable (binary) filename:
```sh
g++ -o binary_name.exe main.cpp
```
If a program uses thread method use command bellow:
```sh
g++ -lpthread main.cpp
```
If a program uses openMP method use command bellow:
```sh
g++ -lopenmp main.cpp
```
#### 11. Execute the binary:
```sh
./a.out
```
or another binary name that was entered after -o option
#### 12. If result wasn't in stdout you need to read "result" file(s):
```sh
cat ~/parallel-programming/500f/result*
```

BIN
pp-lab.pdf Normal file

Binary file not shown.