G
Guest
Помогите синхронизировать потоки с помощью семафора.С++ с использованием стандартных функций CreateSemaphore(),ReleaseSemaphore( ) и тд.
Текст программы предоставляю:
Добавлено: Пробовал написать вот так, но преподаватель сказал что с точки зрения логики это не правильно.
Заранее благодарю за помощь =)
Текст программы предоставляю:
C++:
// при нажатии "1,2…9" -> F=F+1,2…9 (операция 1)
// при нажатии "Alt+1,2…9" -> F=F-1,2…9 (операция 2)
#include <windows.h>
#include <conio.h>
#include <iostream.h>
#include <time.h>
HANDLE hThread; //дискриптор создаваемого потока
DWORD IDThread; //идентификатор потока
int F=0; //разделяемая глобальная переменная
clock_t wtime=100; //время задержки(мс)
void waiting(clock_t dt); //функция задержки
struct log {
int nom; //порядковый номер операции
int key; //код нажатой клавиши
DWORD ID; //идентификатор созданного потока
clock_t t1; //время начала операции
clock_t t2; // время завершения операции
int F; //результат операций в дочернем потоке
int Fc; //результат операций в главном потоке
} mylog[1000]; //неболее 1000 операций
DWORD ThreadProc1(log *p); //функция потока 1 (параметр - pointer на структуру log)
DWORD ThreadProc2(log *p); //функция потока 2 (параметр - pointer на структуру log)
//=================================== ==============
int main() //главный поток
{
int i=0; //счётчик операций
int j=1; //счётчик вывода строк журнала
int key=1; //код нажатой клавиши
int flag=1; //признак завершения программы
int Fcontr; //переменная-дублёр
mylog[1].t2=0; //признак того,что поток не завершён
Fcontr=F;
//Повторять пока flag!=0 или i<1000
while (flag || i >=1000)
{
//Приём кода нажатой клавиши
if (kbhit()!= 0)
{
key= getch();
if (key==0) key=getch();
//Формирование переменной дублёра
if ((key>=49) && (key<=57))
Fcontr=Fcontr+key-48;
else if ((key>=120) && (key<=128))
Fcontr=Fcontr-key+119;
if (key==27)
{
flag=0;
break;
}
//Формируем строку журнала
i++;
mylog[i].nom=i;
mylog[i].key=key;
mylog[i].t2=0;
mylog[i].F=0;
mylog[i].Fc=Fcontr;
mylog[i].t1=clock();
//Создание потока 1 без немедленного запуска
if ((key>=49) && (key<=57))
{
hThread= CreateThread(NULL,0,ThreadProc1,&my log[i],CREATE_SUSPENDED,&IDThread);
}
if ((key>=120) && (key<=128))
{
hThread= CreateThread(NULL,0,ThreadProc2,&my log[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].F << " " << mylog[j].Fc <<endl;
j=++j; //следующая строка журнала
}
} //Повторять пока flag!=0 или i<1000
getch();
return 0;
}
//Функция потока:имитация ”чтения”корректировки
//и ”записи” разделяемой переменной F
//параметр-указатель на текущую строку журнала
DWORD ThreadProc1(log *p)
{
int Fbuf;
//чтение разделяемой переменной в буферную переменную
Fbuf=F;
waiting(wtime); //задержка
//корректировка буферной переменной
if (((*p).key >= 49)&&((*p).key <= 57))
Fbuf=Fbuf+p->key-48;
waiting(wtime);//задержка
//запись из буферной переменной в разделяемую переменную
F=Fbuf;
//запись результата в текущую строку журнала
(*p).F=F;
(*p).t2=clock(); //время окончания работы потока
return 0;
}
DWORD ThreadProc2(log *p)
{
int Fbuf;
//чтение разделяемой переменной в буферную
Fbuf=F;
waiting(wtime); //задержка
//корректировка буферной переменной
if (((*p).key >= 120)&&((*p).key <= 128))
Fbuf=Fbuf-p->key+119;
waiting(wtime);//задержка
//запись результата из буферной переменной в разделяемую
F=Fbuf;
//запись результата в текущую строку журнала
(*p).F=F;
(*p).t2=clock(); //время окончания работы потока
return 0;
}
//функция задержки
//параметр – время задержки в мс
void waiting(clock_t dt) {
clock_t tn;
tn=clock();
while (clock()-tn < dt);
return 0;
}
C++:
#include <windows.h>
#include <conio.h>
#include <iostream.h>
#include <time.h>
HANDLE hThread;
const char lpSemaphoreName[] = "MySemaphore";
HANDLE hSemaphore;
DWORD IDThread;
int F=0;
clock_t wtime=100;
void waiting(clock_t dt);
struct log {
int nom;
int key;
DWORD ID;
clock_t t1;
clock_t t2;
int F;
int Fc;
} mylog[1000];
DWORD ThreadProc1(log *p);
DWORD ThreadProc2(log *p);
//=================================== ==============
int main()
{
int i=0;
int j=1;
int key=1;
int flag=1;
int Fcontr;
mylog[1].t2=0;
Fcontr=F;
hSemaphore = CreateSemaphore(NULL, 0, 1, lpSemaphoreName);
if(hSemaphore == NULL) {
cout<<"Oshibka pri sozdanii semafora!"<<endl;
return 0;
}
while (flag || i >=1000)
{
if (kbhit()!= 0)
{
key= getch();
if (key==0) key=getch();
if ((key>=49) && (key<=57))
Fcontr=Fcontr+key-48;
else if ((key>=120) && (key<=128))
Fcontr=Fcontr-key+119;
if (key==27)
{
flag=0;
break;
}
i++;
mylog[i].nom=i;
mylog[i].key=key;
mylog[i].t2=0;
mylog[i].F=0;
mylog[i].Fc=Fcontr;
mylog[i].t1=clock();
if ((key>=49) && (key<=57))
{
hThread= CreateThread(NULL,0,ThreadProc1,&my log[i],0,&IDThread);
}
if ((key>=120) && (key<=128)){
hThread= CreateThread(NULL,0,ThreadProc2,&my log[i],CREATE_SUSPENDED,&IDThread);}
if (hThread == NULL)
{ cout << "Thread error" << key << endl;
getch();
return 0;
}
else
{
mylog[i].ID=IDThread;
ResumeThread(hThread);
}
WaitForSingleObject(hSemaphore, 30000)
}
if (mylog [j].t2!=0)
{
cout << j << " " << mylog[j].key << " " << mylog[j].ID << " " << mylog[j].t1 << " " << mylog[j].t2 << " " << mylog[j].F << " " << mylog[j].Fc <<endl;
j=++j;
}
}
getch();
return 0;
}
DWORD ThreadProc1(log *p)
{
int Fbuf;
Fbuf=F;
waiting(wtime);
if (((*p).key >= 49)&&((*p).key <= 57))
Fbuf=Fbuf+p->key-48;
waiting(wtime);
if(hSemaphore != NULL)
ReleaseSemaphore(hSemaphore, 1, NULL);
F=Fbuf;
(*p).F=F;
(*p).t2=clock();
return 0;
}
DWORD ThreadProc2(log *p)
{
int Fbuf;
Fbuf=F;
waiting(wtime);
if (((*p).key >= 120)&&((*p).key <= 128))
Fbuf=Fbuf-p->key+119;
waiting(wtime);
if(hSemaphore != NULL)
ReleaseSemaphore(hSemaphore, 1, NULL);
F=Fbuf;
(*p).F=F;
(*p).t2=clock();
return 0;
}
void waiting(clock_t dt) {
clock_t tn;
tn=clock();
while (clock()-tn < dt);
return;
}
Заранее благодарю за помощь =)