Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <Windows.h>
- #include <vector>
- #include <string>
- #include <sstream>
- #include <fstream>
- #include <thread>
- #include <cmath>
- using namespace std;
- const int max_size = 1000;
- HANDLE threads[max_size];
- vector<long double> threadsTime;
- int priority = 0;
- vector<string> words; // all words
- vector<int> res; //max length values that every thread got
- ifstream f;
- string fileName;
- int num; // number of threads
- int n; //number of words
- int ml = 0; // max length of word
- LONG volatile progressCounter = 0;
- double progressMax;
- bool isWorking = true;
- HANDLE ghSemaphore;
- struct thr {
- int id;
- int step;
- };
- // знаходить найбільшу довжину слова зі всіх у масиві результатів
- void findMax() {
- for (int i = 0; i < res.size(); i++) {
- if (res[i] > ml)ml = res[i];
- }
- }
- //записуємо результат
- void writeRes2() {
- HANDLE file = CreateFile(TEXT(R"(C:\Users\BROS\source\repos\OSLab6\OSLab6\res.txt)"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- string res = "";
- res += "Max length: " + to_string(ml) + '\n';
- for (int i = 0; i < threadsTime.size(); i++) {
- cout << "Thread #" << i << " time: " << threadsTime[i] << '\n';
- }
- for (int i = 0; i < threadsTime.size(); i++) {
- ostringstream strs;
- strs << threadsTime[i];
- string tT = strs.str();
- res += "Thread #" + to_string(i) + " time: " + tT + '\n';
- }
- const char* my_chars = res.c_str();
- HANDLE hMapping = CreateFileMapping(file, NULL, PAGE_READWRITE, 0, (strlen(my_chars) * sizeof(char)), NULL);
- LPSTR output = (LPSTR)MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, (strlen(my_chars) * sizeof(char)));
- CopyMemory((LPVOID)output, (LPVOID)my_chars, (strlen(my_chars) * sizeof(char)));
- UnmapViewOfFile(output);
- CloseHandle(hMapping);
- CloseHandle(file);
- }
- // оскільки read2 повертає з файлу string, то цією функцією ми ту стрічку розділяємо на слова і тільки тоді запихуємо у масив
- void split(string s) {
- char delim = ' ';
- size_t start, end = 0;
- while ((start = s.find_first_not_of(delim, end)) != string::npos) {
- end = s.find(delim, start);
- words.push_back(s.substr(start, end - start));
- }
- }
- // зчитує файл
- void read2() {
- string path = "C:\\Users\\BROS\\source\\repos\\OSLab6\\OSLab6\\" + fileName;
- wstring tmp = wstring(path.begin(), path.end());
- const WCHAR* tmp2 = tmp.c_str();
- LPCWSTR p = const_cast<LPCWSTR>(tmp2);
- HANDLE hFile = CreateFile(p, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
- LPSTR input = (LPSTR)MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
- split((string)input);
- UnmapViewOfFile(input);
- CloseHandle(hMapping);
- CloseHandle(hFile);
- }
- // вираховує кількість слів у файлі
- int numOfWords() {
- ifstream file(fileName);
- int num = 0;
- string w;
- while (file >> w) {
- num++;
- }
- file.close();
- return num;
- }
- // функція, яку виконує кожен потік
- DWORD WINAPI maxLen(LPVOID lpParameter) {
- WaitForSingleObject(ghSemaphore, 0L);
- thr* d = (thr*)lpParameter;
- if (d->id < words.size()) {
- chrono::steady_clock::time_point clockStart = chrono::steady_clock::now();
- res[d->id] = words[d->id].length();
- for (int i = d->id + d->step; i < words.size(); i += d->step) {
- if (res[d->id] < words[i].length()) res[d->id] = words[i].length();
- InterlockedIncrement(&progressCounter);
- }
- chrono::steady_clock::time_point clockEnd = chrono::steady_clock::now();
- chrono::steady_clock::duration timeSpan = clockEnd - clockStart;
- double nseconds = double(timeSpan.count()) * chrono::steady_clock::period::num / chrono::steady_clock::period::den;
- threadsTime[d->id] = nseconds;
- }
- ReleaseSemaphore(ghSemaphore, 1, NULL);
- ExitThread(0);
- }
- // функція для потоку, який показує нам прогрес
- DWORD WINAPI showProgress(LPVOID lpParameter) {
- while (isWorking) {
- cout.precision(3);
- cout << progressCounter / progressMax * 100 << "%" << endl;
- int l = res[0];
- for (int j = 0; j < res.size(); j++) {
- if (l < res[j]) {
- l = res[j];
- }
- }
- if (l > 1) cout << "Len = " << l << endl;
- }
- ExitThread(0);
- }
- // створюємо потоки
- bool aThr(int count) {
- n = words.size();
- progressMax = words.size();
- const unsigned pCount = 1U * num;
- res.resize(num, 0);
- threadsTime.resize(num, 0);
- ghSemaphore = CreateSemaphore(NULL, count, count, NULL);
- if (ghSemaphore == NULL) {
- cout << "\nWe got a problem with the Semaphore\n\n";
- return false;
- }
- HANDLE progr = CreateThread(NULL, 0, showProgress, NULL, 0, 0);
- if (progr == NULL) {
- cout << "\nWe got a problem with the Progress Thread\n\n";
- return false;
- }
- for (int i = 0; i < pCount; i++) {
- thr* d = new thr;
- d->id = i;
- d->step = pCount;
- threads[i] = CreateThread(0, 0, maxLen, (LPVOID)d, 0, 0);
- }
- SetThreadPriority(threads[0], priority);
- WaitForMultipleObjects(num, threads, TRUE, INFINITE);
- for (int i = 0; i < pCount; i++) {
- WaitForSingleObject(threads[i], INFINITE);
- }
- for (DWORD i = 0; i < pCount; ++i) {
- CloseHandle(threads[i]);
- }
- isWorking = false;
- WaitForSingleObject(progr, INFINITE);
- cout << "\nDone!\n";
- return true;
- }
- void changePriority() {
- cout << "Time critical - 15\n";
- cout << "Highest - 2\n";
- cout << "Above normal - 1\n";
- cout << "Normal - 0\n";
- cout << "Below normal - -1\n";
- cout << "Lowest - -2\n";
- cout << "Idle - -15\n";
- cin >> priority;
- }
- int main()
- {
- cout << "Number of threads: ";
- cin >> num;
- int choice, maxCount = num;
- cout << "Would you like to limit the number of threads working at the same time? Yes - 1, No - 0 | ";
- cin >> choice;
- if (choice == 1) {
- cout << "Number of threads working at the same time: ";
- cin >> maxCount;
- }
- cout << "Would you like to change priority level of the first thread? Yes - 1, No - 0 | ";
- cin >> choice;
- if (choice == 1) changePriority();
- cout << "Name of file: ";
- cin >> fileName;
- read2();
- if (aThr(maxCount)) {
- findMax();
- cout << "Max length: " << ml << endl;
- writeRes2();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement