1. Пользуйтесь тегами кода. - [code] ... [/code] 2. Точно указывайте язык, название и версию компилятора (интерпретатора). 3. Название темы должно быть информативным. В описании темы указываем язык!!!
Проблема вот в чем : в функциях win32api CreateThread и _beginthreadex как параметр функции-потока передается указатель на void. Для bcw 5.5 подойдет любой параметр,а вот gcc выдает ошибку о неправильном использовании void-параметра. Как обойти?переносить код на borland c++ 5.5 времени нет, да и исправлять всё там муторно.. в VS08 этот проект так же не переноситься..как быть?
с этим понятно. Интересно, как же я бы сам смог до такого дойти, с нашими институтскими методичками.Спасибо большое. Только теперь другой вопрос : вот такой вот код :
Куда проподает последний вызов?Точнее нет, он не проподает, я знаю. (если в конце поставить 2 cin.get(), то его можно увидеть после считывания символов), но все же, почему же 4 вызова происходят в один момент времени, а последний, 5ый, можно сказать "после завершения программы". Кстате, если использовать параметр функции потока как std::string* то вообще ничего не происходит. volvo, пожалуйста, разъясни ситиацию, я уже совсем ничего не понимаю.
как же я бы сам смог до такого дойти, с нашими институтскими методичками
У тебя ж выход в Сеть есть? А в MSDN явно сказано, что третий параметр у CreateThread Function имеет тип LPTHREAD_START_ROUTINE... А если компилятор не может привести типы сам, надо попытаться ему помочь, в большинстве случаев это срабатывает.
Цитата
почему же 4 вызова происходят в один момент времени, а последний, 5ый, можно сказать "после завершения программы"
То есть, ты на 100% уверен, что запаздывает именно пятый поток? Мне очень жаль тебя огорчать, конечно, но это не так... Смотри:
Так какой поток запаздывает, говоришь? А все потому, что передал-то я адрес переменной, но чему она равна в тот момент, когда начинает работать поток, и существует ли она вообще? При всем этом я и получать должен адрес, а не что-то иное... Кстати, еще одно: поток не завершается потому, что для гарантированного завершения функция prf должна вернуть значение. У тебя это невозможно, поскольку описана функция как void, а ведь MSDN предупреждает:
Цитата
Do not declare this callback function with a void return type and cast the function pointer to LPTHREAD_START_ROUTINE when creating the thread. Code that does this is common, but it can crash on 64-bit Windows.
path += "\\"; hFile = FindFirstFile(s, &dFile); if (hFile != INVALID_HANDLE_VALUE) { do { vect.push_back(path + dFile.cFileName); } while (FindNextFile(hFile, &dFile) != 0); FindClose(hFile); } }
unsigned int GetDividerCount(std::string &s, char& devider)//not changed { int count = 0; for (unsigned int i = 0; i < s.size(); i++) if (s.at(i) == devider) count++; return count; }
std::string Parser(std::string &s, char& devider)//not changed { std::string bufs; int n = s.find('.'); bufs.append(s, 0, n); s.erase(0, n + 1); return bufs; }
{ ofstream outfile("result.txt", std::ios::app); outfile << "\nFive longest strings for file " << " : \n"; for (unsigned int i = 0; i < 5; i++) outfile << i + 1 << " - " << PS[i] << "\n"; outfile << "\nTotal count of parsed strings for this file : " << parsedst << "\n"; outfile.close(); }
bool MainFunction(std::string *v) { std::string String;//целая строка из файла std::vector<std::string> PS;// вектор разбитых строк char d = '.';//разделитель предложений std::size_t parsedst = 0;//кол-во обработанных строк unsigned int dcount = 0;//кол-во разделителей в файле определяет кол-во предложений в файле. String = GetStringFromFile(*v); dcount = GetDividerCount(String, d); for (unsigned int j = 0; j < dcount; j++) PS.push_back(Parser(String, d)); std::sort(PS.begin(), PS.end(), comp); parsedst = PS.size(); SaveResults(PS, parsedst); return TRUE; }
Запускается через командную строку, ввиде : prog.exe *ПУТЬ к папке с файлами формата txt* *кол-во файлов для обработки* Например C:\some\pr.exe C:\1 10. Программа читает файлы и создает результирующий файл, в котором записываются 5 самых длинных предложений для каждого файла. Предложения разделяются символом "." . Прикладываю архив с файлами для обработки. Проблема вот в чем, я раньше выкладывал этот код для одно-потокового варианта, сейчас надо организовать многопоточность. Основная проблема в том, что в результирующем файл записываются результаты не для всех файлов. В принципе, это наверное из-за асинхронизации процессов. Необходимо использовать какие-либо средства для синхронизации?Ну, допустим, мьютексы. Я прав? Если нет , то в чем ошибка?
Необходимо использовать какие-либо средства для синхронизации?
Необходимо запрещать доступ к файлу, в который пишется информация, одновременно нескольким потокам... Проще всего - реализовать через Event-ы: в начале работы программы создаешь событие, которое будет контролировать доступ к файлу результатов:
HANDLE myEvent; // в H-файле эта переменная описана через extern
, а для того, чтобы гарантировать, что пока один поток пишет в файл, другой будет ждать освобождения файла, чуть-чуть меняешь функцию потока:
bool MainFunction(std::string *v) { std::string String; // целая строка из файла std::vector<std::string> PS; // вектор разбитых строк char d = '.'; // разделитель предложений std::size_t parsedst = 0; // кол-во обработанных строк unsigned int dcount = 0; // кол-во разделителей в файле определяет кол-во предложений в файле. String = GetStringFromFile(*v); dcount = GetDividerCount(String, d); for (unsigned int j = 0; j < dcount; j++) PS.push_back(Parser(String, d)); std::sort(PS.begin(), PS.end(), comp); parsedst = PS.size();
WaitForSingleObject(myEvent, INFINITE); // если Event сброшен - ждать SaveResults(PS, parsedst); SetEvent(myEvent); // По окончании записи в файл разрешить записывать другим
return TRUE; }
Вот и все, теперь информация от всех тредов будет сохранена...
SetEvent(myEvent); // и сразу же его устанавливаем, чтоб не держать потоки for (int i = 0; i < atoi(argv[2]); i++){ TH[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) MainFunction, &Paths[i], 0, &id[i]);//создаем потоки SetThreadPriority(TH[i],THREAD_PRIORITY_HIGHEST);//изменяем приоритет созданного потока
Время исполнения не изменяется в лучшую сторону, а иногда даже ухудщается.. вот файл с тестами. A - вариант с однопоточным. B - вариант с многопоточным. C - вариант с изменением приоритетов. h - чтение с hdd f - с flash.
Время исполнения не изменяется в лучшую сторону, а иногда даже ухудщается..
Во-первых, как ты замерял время?
Во-вторых, кто тебе сказал, что при при изменении приоритета потока это изменение вообще влияет на скорость выполнения данного потока? Ну, допустим, у тебя поток теперь имеет THREAD_PRIORITY_HIGHEST. А сам процесс твой с каким приоритетом работает?
Дальше: ты работаешь с диском, а это уже медленно, имеет ли смысл повышать приоритет, чтоб работать с медленными устройствами? Кроме всего прочего, Windows сама прекрасно может динамически менять приоритет твоего потока (что может отрицательно сказаться на быстродействии приложения, были жалобы, об этом есть у Рихтера), именно по этой причине есть функции SetProcessPriorityBoost / SetThreadPriorityBoost
Ну, и напоследок...
Если уж ты действительно хочешь попробовать изменить приоритет потока, то создавай поток "спящим", потом меняй приоритет, и потом "буди" поток, так будет лучше.
1 . Мне по заданию надо использовать функцию повышения приоритета , добившись тем самым , как написано " Заметного прироста скорости работы". 2 . Замеряю так :
int main(int argc, char *argv[]) { if (argc < 3 || atoi(argv[2]) < 0 || atoi(argv[2]) == 0 || atoi(argv[2]) > 10) { cout << "Not enought parametrs of wrong file number parameter"; exit(0); } clock_t tS, tE;//Переменные для фиксации начала и конца обработки tS = clock(); ... WaitForMultipleObjects(atoi(argv[2]), TH, TRUE, INFINITE);//ждем завершения всех потоком tE = clock(); outfile << "\nTime elapsed : " << tE - tS << " miliseconds"; outfile.close(); return 0; }
3. процесс работает с нормальным приоритетом . т.е normal class. Насчет создания спящем..сейчас попробую