Синхронизация потоков в пользовательском режиме с помощью Interlocked-функций Задача: После запуска программы основной процесс спрашивает путь к файлу с вектором для суммирования. Файл содержит элементы вектора (положительные целые числа), разделенные символом ','. Считав данные из файла, программа выводит количество элементов и спрашивает о количестве необходимых потоков для вычисления суммы. Распределив поровну элементы вектора между введенным количеством потоков, основной процесс создает потоки, передавая в них части вектора. Поток, на основе входных данных, суммирует элементы вектора, занося результат в общую переменную. По завершению работы потока, на экран выводится сообщение с информацией о номере потока и его вычисленной сумме. После того, как все потоки закончат работу, основной процесс выводит общий результат суммирования. Программа работает нормально, но с течением времени сказали изменить этот текстовый файл в котором хранится вектор, содержимое файла было в одну строку и все работало хорошо, но теперь у нас там две строки с данными, а наша программа работает только с одной. Нам подсказали, что нужно сделать вместо одного fgets два и как то их там объеденить. Подскажите как это сделать? | Цитата | #include <iostream> #include <conio.h> #include <stdlib.h> #include <windows.h>
using namespace std;
LONG Sum = 0; // Глобальная переменная для суммы элементов вектора
// Объявление структуры Вектор (с псевдонимом ВЕКТОР) typedef struct Vector { int *data; // элементы вектора int count; // количество элементов } VECTOR;
// Функция потока DWORD WINAPI ThreadFunc(LPVOID vect) { VECTOR* vec; vec = (VECTOR*)vect; int vecsum = 0; for(int i = 0; i < vec->count; i++) vecsum += vec->data[i]; InterlockedExchangeAdd(&Sum, vecsum); }
int main(void) { VECTOR vecf, *vect; // структура для общего вектора, считанного с файла, и для массива векторов для потоков DWORD *dwThreadIds, dwThreadsCount, dwElemInThread; //массив идентификаторов потока, кол-во потоков, кол-во элементов в потоке соответсвенно HANDLE *hThread; //массив дескрипторов потока FILE *hFile; // дескриптор открываемого файла char *tmp; // строка для имени файла и для его содержимого BOOL parity; // четность деления кол-ва потоков и кол-ва элементов
vecf.count = 0; cout << "Enter full path to file" << endl << "> "; cin >> tmp; delete [] tmp;
hFile = fopen(tmp, "rt"); if (hFile == NULL) { cout << "Error: Invalid filename." << endl; return 1; } fseek(hFile, 0, SEEK_END); // file int fsize = ftell(hFile) + 1; // bytes fseek(hFile, 0, SEEK_SET); // count tmp = new char[fsize]; fgets(tmp, fsize, hFile); for (int i = 0; tmp[i] != '\0'; i++) // подсчет запятых в строке (для подсчета элементов вектора) if(tmp[i] == ',') vecf.count++; vecf.data = new int[vecf.count+1]; // memory alloc for vector data ( ',' count = 5, elements count = 5+1) cout << "Given vector: "; vecf.count = 0; // Разбиение строки на элементы (с использованием разделителя ",") vecf.data[0] = atoi(strtok(tmp, ",")); // atoi - перевод строки в число while (vecf.data[vecf.count] != '\0') { cout << vecf.data[vecf.count] << " "; vecf.count++; vecf.data[vecf.count] = atoi(strtok(NULL, ",")); } delete [] tmp;
cout << endl << "Elements count: " << vecf.count << endl; cout << "Enter threads count: " << endl << "> "; cin >> dwThreadsCount; if (dwThreadsCount > vecf.count) { cout << "Error: Enter number of threads less than number of elements." << endl; return 2; }
vect = new VECTOR[dwThreadsCount]; dwThreadIds = new DWORD[dwThreadsCount]; hThread = new HANDLE[dwThreadsCount]; if (vecf.count % dwThreadsCount == 0) // определяем, четно ли делится кол-во элементов на кол-во потоков parity = TRUE; else parity = FALSE; dwElemInThread = vecf.count / dwThreadsCount; int offset = 0; for (unsigned int a = 0; a < dwThreadsCount; a++) { if (a == 0 && parity == FALSE) vect[a].count = dwElemInThread + (vecf.count % dwThreadsCount); else vect[a].count = dwElemInThread; vect[a].data = new int[vect[a].count]; for (int j = 0; j < vect[a].count; j++) vect[a].data[j] = vecf.data[j+offset]; offset += vect[a].count; hThread[a] = CreateThread(NULL, 0, ThreadFunc, &vect[a], 0, &dwThreadIds[a]); //создание потока }
WaitForMultipleObjects(dwThreadsCou nt, hThread, TRUE, INFINITE); // wait for thread ending cout << "Sum of elements = " << Sum << endl; for (unsigned int a = 0; a < dwThreadsCount; a++) delete [] vect[a].data; delete [] vecf.data; delete [] vect; delete [] dwThreadIds; delete [] hThread; fclose(hFile); _getch(); return 0; }
|
|