Проблема вот в чем : в функциях win32api CreateThread и _beginthreadex как параметр функции-потока передается указатель на void. Для bcw 5.5 подойдет любой параметр,а вот gcc выдает ошибку о неправильном использовании void-параметра. Как обойти?переносить код на borland c++ 5.5 времени нет, да и исправлять всё там муторно.. в VS08 этот проект так же не переноситься..как быть?
Показывай описание функции потока, и то, как ты пытаешься вызвать CreateThread
ну, допустим, вот пример простой :
#include <iostream>
#include <string>
#include <windows.h>
void prf(int i)
{
std::cout << i;
}
int main(int argc, char* argv[])
{
int i;
HANDLE ITT;
DWORD ID;
ITT=CreateThread(NULL,0,prf,&i,CREATE_SUSPENDED,&ID);
}
Ну, вот тебе пример вызова, который компилируется без ошибок:
#include <iostream>
#include <string>
#include <windows.h>
void prf(int i)
{
std::cout << i;
}
int main(int argc, char* argv[])
{
int i;
HANDLE ITT;
DWORD ID;
ITT=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)prf,&i,CREATE_SUSPENDED,&ID);
}
void prf(int* i), требуется же указатель, а не что-то другое...
с этим понятно. Интересно, как же я бы сам смог до такого дойти, с нашими институтскими методичками.Спасибо большое. Только теперь другой вопрос :
вот такой вот код :
void prf( std::string fname)
{
std::cout << fname;
}
int main(int argc, char* argv[])
{
std::string fname="file";
HANDLE ITT[6];
DWORD ID;
for(int i=0;i<5;i++)
ITT[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)prf,&fname,0,&ID);
}
#include <iostream>Так какой поток запаздывает, говоришь? А все потому, что передал-то я адрес переменной, но чему она равна в тот момент, когда начинает работать поток, и существует ли она вообще? При всем этом я и получать должен адрес, а не что-то иное... Кстати, еще одно: поток не завершается потому, что для гарантированного завершения функция prf должна вернуть значение. У тебя это невозможно, поскольку описана функция как void, а ведь MSDN предупреждает:
#include <string>
#include <windows.h>
void prf( std::string fname)
{
std::cout << fname;
}
int main(int argc, char* argv[])
{
std::string fname="file";
HANDLE ITT[6];
DWORD ID;
for(int i=0;i<5;i++) {
std::string s = fname + (char)(i + '0');
ITT[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)prf,&s,0,&ID);
}
}
#include <iostream>
#include <string>
#include <windows.h>
DWORD prf(std::string *s)
{
std::cout << *s << std::endl;
return 0;
}
int main(int argc, char* argv[])
{
std::string fname="file";
HANDLE ITT[5]; // Зачем у тебя здесь было 6?
std::string strs[5]; // !!!
DWORD ID;
for(int i=0;i<5;i++) {
strs[i] = fname + (char)(i + '0'); // !!!
ITT[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)prf,&strs[i],0,&ID);
}
WaitForMultipleObjects(5, ITT, TRUE, INFINITE); // ждем завершения всех потоков
return 0;
}
Спасибо, volvo.. После этого поста, я думаю у тебя появиться желание меня убить) Вообщем, код исходный :
main
#include "interface.h"
int main(int argc, char *argv[])
{
DWORD id[10];
HANDLE TH[10];
clock_t tS, tE;
std::vector<std::string> Paths;
tS=clock();
GetFileList(argv, Paths);
for (int i = 0; i < atoi(argv[2]); i++)
TH[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) MainFunction,
&Paths[i], 0, &id[i]);
WaitForMultipleObjects(atoi(argv[2]), TH, TRUE, INFINITE);
tE=clock();
return 0;
}
#include <algorithm>
#include <iostream.h>
#include <process.h>
#include <windows.h>
#include <fstream.h>
#include <string>
#include <vector.h>
std::string GetStringFromFile(std::string &fname);
void GetFileList(char *argv[], std::vector<std::string>& vect);// Получает список файлов по заданной маске
std::string Parser(std::string &s, char& devider);
unsigned int GetDividerCount(std::string &s, char& devider);
bool comp(std::string s1, std::string s2);
std::string NameGenerator(char *argv[]);
void SaveResults (std::vector<std::string> &PS,std::size_t &parsedst);//changed
bool MainFunction(std::string *v);
#include "interface.h"
std::string GetStringFromFile(std::string &fname)//changed
{
std::string xstr;
std::ifstream xfile;
xfile.open(fname.data(), std::ios::binary);
xfile.seekg(0, std::ios_base::end);
xstr.resize(xfile.tellg());
xfile.seekg(0, std::ios_base::beg);
//копируем данные
char mychar[xstr.size()];
xfile.read(mychar, xstr.size());
xfile.close();
xstr = mychar;
return xstr;
}
void GetFileList(char *argv[], std::vector<std::string>& vect)//not changed
{
WIN32_FIND_DATA dFile;
HANDLE hFile;
std::string path;
char s[MAX_PATH] = "";
lstrcpy(s, argv[1]);
path = s;
lstrcat(s, "\\*.txt");
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;
}
bool comp(std::string s1, std::string s2)//not changed
{
return s1.size() > s2.size();
}
std::string NameGenerator(char *argv[])//not changed
{
std::string fname = "Result_____.txt";
SYSTEMTIME st;
GetSystemTime(&st);
fname.insert(7, argv[2]);
char ch[3];
itoa(st.wHour + 3, ch, 10);
if (fname.size() == 17)
fname.insert(10, ch);
else
fname.insert(9, ch);
itoa(st.wMinute, ch, 10);
if (fname.size() == 19)
fname.insert(13, ch);
else
fname.insert(12, ch);
itoa(st.wSecond, ch, 10);
if (fname.size() == 21)
fname.insert(16, ch);
else
fname.insert(15, ch);
return fname;
}
void SaveResults(std::vector<std::string> &PS, std::size_t &parsedst)//changed
{
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;
}
HANDLE myEvent; // в H-файле эта переменная описана через extern, а для того, чтобы гарантировать, что пока один поток пишет в файл, другой будет ждать освобождения файла, чуть-чуть меняешь функцию потока:
int main(int argc, char *argv[])
{
DWORD id[10] = {0};
HANDLE TH[10] = {0};
clock_t tS, tE;
myEvent = CreateEvent(NULL, FALSE, FALSE, NULL); // Создаем событие,
SetEvent(myEvent); // и сразу же его устанавливаем, чтоб не держать потоки
std::vector<std::string> Paths;
tS=clock();
GetFileList(argv, Paths);
for (int i = 0; i < atoi(argv[2]); i++) {
TH[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) MainFunction,
&Paths[i], 0, &id[i]);
}
WaitForMultipleObjects(atoi(argv[2]), TH, TRUE, INFINITE);
tE=clock();
return 0;
}
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);//изменяем приоритет созданного потока
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;
}