Помощь - Поиск - Пользователи - Календарь
Полная версия: не пойму в чем ошибка.Потоки,winapi.
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ада и другие языки
Andrewshkovskii
Всем привет!Давно я тут не было!не программировал с конца июня, многое подзабыл уже..без практики тяжело..Вот дали лабу в инсте, вроде как все правильно написал(точнее переделал пример в лабе, но это лишь затем, что бы посмотреть как будет работать). Но возникла проблема : gcc ошибок не видит, ну разве только ругается на winapi функции, но это из-за MinGW. А вот компилятор борланда выдает..
Вот код, для начала :
#include <windows.h>
#include <conio.h>
#include <iostream.h>
#include <time.h>
#include <string>

using namespace std;
HANDLE hThread; // дескриптор создаваемого потока
DWORD IDThread; // идентификатор потока

string F1="0";
string F2="1"; // разделяемая глобальная переменная
clock_t wtime=100; // время задержки (мс)
void waiting(clock_t dt); // функция задержки
// Журнал
struct log {
int nom; // порядковый номер операции
int key; // код нажатой клавиши
DWORD ID; // идентификатор созданного потока
clock_t t1; // время начала операции
clock_t t2; // время завершения операции
string F1;
string F2; // результат операции в дочернем потоке
string Fc1;
string Fc2; // результат операции главном потоке
// (переменная-дублер)
} mylog[1000]; // не более 1000 строк в журнале

DWORD ThreadProc(log *p); // функция потока (параметр -
// указатель на структуру log)
//=================================================
int main() // главный поток
{
int i=0; // счетчик операций
int j=1; // счетчик вывода строк журнала
int key=1; // код нажатой клавиши
int flag=1; // признак завершения программы
string Fcontr1,Fcontr2; // переменная-дублер
mylog[1].t2=0; // признак того, что поток не завершен
Fcontr1=F1;
Fcontr2=F2;

// повторять пока flag !=0 или i<1000
while (flag || i >=1000)
{
//Прием кода нажатой клавиши
if (kbhit()!= 0)
{
key= getch();
// формирование переменной-дублера
if (key == 49) Fcontr2+=Fcontr1[0];
else Fcontr1+=Fcontr2[0];
//Проверка кода нажатой клавиши
switch (key)
{
case 27 : {flag=0; break;} // признак выхода из
// программы (Esc)
case 49 : // нажата клавиша "1"
case 50 : // нажата клавиша "2"
{
i=++i; //следующая операция
// формируем строку журнала
mylog[i].nom=i;
mylog[i].key=key;
mylog[i].t2=0;
mylog[i].F1="0";
mylog[i].F2="1";
mylog[i].Fc1=Fcontr1;
mylog[i].Fc2=Fcontr2;
mylog[i].t1=clock();
// создание потока без немедленного запуска
hThread= CreateThread(NULL,0,ThreadProc,&mylog[i],CREATE_SUSPENDED,&IDThread);
if (hThread == NULL)
{ cout << "Thread error" << key << endl;
getch();
return 0;
}
else
{
// запуск потока
mylog[i].ID=IDThread;
ResumeThread(hThread);
}
}
}
}
// завершение работы потока проверяется по
// сформированному в функции
// потока значению времени t2
if (mylog [j].t2!=0)
{
// вывод j-й строки журнала
cout << j << " " << mylog[j].key << " " << mylog[j].ID << " " << mylog[j].t1 << " " <<
mylog[j].t2 << " " << mylog[j].F1 << " " << mylog[j].F2 << " " << mylog[j].Fc1 << " " <<
mylog[j].Fc2 <<endl;
j=++j; // следующая строка журнала
}
} // повторять пока flag !=0 или i<1000
getch();
return 0;
}

// функция потока: имитация "чтения", корректировки
// и "записи" разделяемой переменной F
// параметр - указатель на текущую строку журнала

DWORD ThreadProc(log *p)
{
string Fbuf1;
string Fbuf2;
// чтение разделяемой переменной в буферную переменную
Fbuf1=F1;
Fbuf2=F2;
waiting(wtime); // задержка
// корректировка буферной переменной
if ((*p).key == 49) Fbuf2+=Fbuf1[0];
else Fbuf1+=Fbuf2[0];
waiting(wtime); // задержка
// запись из буферной переменной в разделяемую переменную
F1=Fbuf1;
F2=Fbuf2;
// запись результата в текущую строку журнала
(*p).F1=F1;
(*p).F2=F2;
(*p).t2=clock(); // время окончания работы потока
return 0;
}

// функция задержки
// параметр - время задержки в мс
void waiting(clock_t dt) {
clock_t tn;
tn=clock();
while (clock()-tn < dt);
return;
}



Задание звучит так : 1. Разработать консольное многопоточное приложение, выполняющее корректировку разделяемых данных, определенных одной или двумя глобальными переменными, по следующему алгоритму. Главный поток отслеживает нажатие пользователем клавишей двух типов. В случае нажатия на клавиши 1-го типа выполняется операция 1, при нажатии на клавиши 2-го типа выполняется операция 2. Функциональность каждой операции определяется в соответствии с заданным вариантом (табл. 1). Начальные значения разделяемых переменных установить самостоятельно.
Для выполнения операций 1 и 2 в программе создаются отдельные потоки. В потоке имитируются действия по "чтению" разделяемых переменных в буферные переменные, и "записи" полученных результатов из буферных переменных с учетом некоторой временной задержки (см. пример в приложении). В программе заданные операции оформляются либо в виде одной функции потока (варианты с индексом а), либо двумя функциями потока (варианты с индексом b).
. У меня надо было копировать буквы из строк, но не в этом суть дела.
При компилировании в борланде, компилятор выдает :
что вот тут
DWORD ThreadProc(log *p); // функция потока (параметр -
// указатель на структуру log)

'log' Cannot start a parametr declaration.
Не понимаю, почему?..Гцц этой ошибки не видит.
volvo
Цитата
При компилировании в борланде, компилятор выдает :
что вот тут
DWORD ThreadProc(log *p); // функция потока (параметр -
// указатель на структуру log)

'log' Cannot start a parametr declaration.
Потому что Борланд хочет, чтоб ты написал

DWORD ThreadProc(struct log *p);
, что будет компилироваться и им и GCC (проверено в GCC 3.4.5 и в Builder 2009)... Но ни тот ни другой не пропустят эту функцию в CreateThread, поскольку подразумевается
DWORD WINAPI ThreadProc(
__in LPVOID lpParameter
);
, то есть параметр должен быть (void *)...
Andrewshkovskii
Понятно..просто программирование это как английский, без практики забываются основы..а я месяца 4 не писал ничего...Хотя в методических указаниях, этот пример написан именно так, и он работает, но когда я подставил под своё задание(фактически добавил строки и их обработку) начало выдавать такую ошибку..
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.