Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.03.2011, 14:17   #1
ZBEP
Форумчанин
 
Аватар для ZBEP
 
Регистрация: 23.03.2009
Сообщений: 334
По умолчанию

counter, т.е. например так?

Код:
void Test1(void *)
{
	cout<<"Тест 1 Запуск\n";
	DWORD dwWaitResult; 
	do
	{
		dwWaitResult = WaitForSingleObject(hSemaphore,1);
		Mas[1]=1;
		cout<<"Тест 1 TIMEOUT\n";
	}

	while(dwWaitResult==WAIT_OBJECT_0);
	Sleep(1000);
	if (ReleaseSemaphore(hSemaphore,1,NULL))
	cout<<"\nReleaseSemaphore Ok Тест 1. ";
	_endthread();
}
ZBEP вне форума Ответить с цитированием
Старый 10.03.2011, 14:17   #2
ZBEP
Форумчанин
 
Аватар для ZBEP
 
Регистрация: 23.03.2009
Сообщений: 334
По умолчанию

counter, т.е. например так?

Код:
void Test1(void *)
{
	cout<<"Тест 1 Запуск\n";
	DWORD dwWaitResult; 
	do
	{
		dwWaitResult = WaitForSingleObject(hSemaphore,1);
		Mas[1]=1;
		cout<<"Тест 1 TIMEOUT\n";
	}

	while(dwWaitResult==WAIT_OBJECT_0);
	Sleep(1000);
	if (ReleaseSemaphore(hSemaphore,1,NULL))
	cout<<"\nReleaseSemaphore Ok Тест 1. ";
	_endthread();
}
ZBEP вне форума Ответить с цитированием
Старый 10.03.2011, 18:34   #3
ZBEP
Форумчанин
 
Аватар для ZBEP
 
Регистрация: 23.03.2009
Сообщений: 334
По умолчанию C++ Семофоры

Здравствуйте!
Мне тут дали задание, но я что-то не совсем понял, что от меня хотят.
Цитата:
Создайте разделяемый ресурс в виде глобального массива типа int и обеспечьте при помощи семафоров, единовременный доступ к элементам массива только одного потока. Другие потоки должны дожидаться очереди для доступа к общему ресурсу.
Может кто-нибудь объяснить что от меня хотят?

Вот код самой "программы"
Код:
#include "stdafx.h"
#include "windows.h"
#include "process.h" 

HANDLE hSemaphore;
LONG cMax = 3;
int Mas[10];

void Test1(void *);
void Test2(void *);

CWinApp theApp;
using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{setlocale(LC_CTYPE, "");
	int nRetCode = 0;
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		cout<<"Критическая ошибка: неудачная инициализация MFC\n";
		nRetCode = 1;
	}
	else
	{
		hSemaphore = CreateSemaphore( 
		NULL,// нет атрибута
		cMax,// начальное состояние
		cMax,// максимальное состояние
		NULL// без имени
		);

		 if (!hSemaphore == NULL) 
		 {
			if (_beginthread(Test1,1024,NULL)==-1)
			cout<<"Ошибка потока\n";

			if (_beginthread(Test2,1024,NULL)==-1)
			cout<<"Ошибка потока\n";

			//sleep(100000);
			system("pause");
			CloseHandle(hSemaphore);
		 }
		 else
		 {
			cout<<"Ошибка создания семофора\n";
		 }
	 }

	return nRetCode;
}


void Test1(void *)
 {

	cout<<"Тест 1 Запуск\n";
	DWORD dwWaitResult; 
 do
 {
	dwWaitResult = WaitForSingleObject( 
	hSemaphore,// указатель на семафор
	1// интерфал ожидания
	);
	cout<<"Тест 1 TIMEOUT\n";
 }
 while(dwWaitResult==WAIT_OBJECT_0);
 Sleep(1000);
 if (ReleaseSemaphore(       
  hSemaphore,// указатель на семафор
  1,// изменяет счетчик на 1
        NULL)
 )
cout<<"\nReleaseSemaphore Ok Тест 1";
_endthread();
}

void Test2(void *)
{
 DWORD dwWaitResult;
 cout<<"Тест 2 Запуск\n";
 do
 {
  dwWaitResult = WaitForSingleObject(hSemaphore,1);
  cout<<"Тест 2 TIMEOUT\n";
 }
 while(dwWaitResult==WAIT_OBJECT_0);
 Sleep(1000);
 if (ReleaseSemaphore(hSemaphore,1,NULL))
 cout<<"\nReleaseSemaphore Ok Тест 2";
 _endthread();
}

Последний раз редактировалось ZBEP; 10.03.2011 в 18:37.
ZBEP вне форума Ответить с цитированием
Старый 10.03.2011, 18:53   #4
counter
Участник клуба
 
Регистрация: 18.10.2008
Сообщений: 1,409
По умолчанию

Цитата:
Сообщение от ZBEP Посмотреть сообщение
Вот код самой "программы"
А где вы ее взяли ,если не секрет?
counter вне форума Ответить с цитированием
Старый 10.03.2011, 19:09   #5
ZBEP
Форумчанин
 
Аватар для ZBEP
 
Регистрация: 23.03.2009
Сообщений: 334
По умолчанию

counter, ну изначально кусок кода был в самом задании, это уже измененный мной, там нужно было выполнить пару легких заданий и т.д.
Осталось только доступ к массиву ограничить, ток я не совсем представляю себе это..

Как понять доступ к элементу массива?
Доспуп к числу.. Это же не файл.
Или просто выводить это число при выполнении какого-нить из потоков, и если это число выведено в первом потоке, то остальные потоки ждут?
Ждут чего? Завершения потока?

Последний раз редактировалось ZBEP; 10.03.2011 в 19:27.
ZBEP вне форума Ответить с цитированием
Старый 10.03.2011, 19:59   #6
counter
Участник клуба
 
Регистрация: 18.10.2008
Сообщений: 1,409
По умолчанию

вы знаете, что такое синхронизация потоков и для чего она нужна?
читать тут
Цитата:
Сообщение от ZBEP Посмотреть сообщение
Как понять доступ к элементу массива?
Доспуп к числу.. Это же не файл.
вам нужно разграничить доступ потоков к массиву, т.е чтобы при работе одного потока с массивом другой поток не мог обрашаться к этому массиву.
Код:
void Test1(void *)
 {

	cout<<"Тест 1 Запуск\n";
	DWORD dwWaitResult; 
 
         dwWaitResult = WaitForSingleObject(hSemaphore,INFINITE);

          // тут работаем с массивом
          // второй поток ожидает

         if (ReleaseSemaphore(hSemaphore,1,NULL))
          cout<<"\nReleaseSemaphore Ok Тест 1";
}
counter вне форума Ответить с цитированием
Старый 10.03.2011, 22:31   #7
ZBEP
Форумчанин
 
Аватар для ZBEP
 
Регистрация: 23.03.2009
Сообщений: 334
По умолчанию

counter, т.е. если сделать так:
Код:
#include "stdafx.h"
#include "windows.h"
#include "process.h" 

HANDLE hSemaphore;
LONG cMax = 3;
int Mas[10];
void Test1(void *);
void Test2(void *);
void Test3(void *);
void Test4(void *);

CWinApp theApp;
using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{setlocale(LC_CTYPE, "");
	int nRetCode = 0;

	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		cout<<"Критическая ошибка: неудачная инициализация MFC\n";
		nRetCode = 1;
	}
	else
	{
		hSemaphore = CreateSemaphore( 
		NULL,// нет атрибута
		cMax,// начальное состояние
		cMax,// максимальное состояние
		NULL// без имени
		);

		 if (!hSemaphore == NULL) 
		 {
			if (_beginthread(Test1,1024,NULL)==-1)
			cout<<"Ошибка потока\n";
			if (_beginthread(Test2,1024,NULL)==-1)
			cout<<"Ошибка потока\n";
			if (_beginthread(Test3,1024,NULL)==-1)
			cout<<"Ошибка потока\n";
			if (_beginthread(Test4,1024,NULL)==-1)
			cout<<"Ошибка потока\n";
			Sleep(4000);
			cout<<"\n\nПоследний доступ к массиву у потока "<<Mas[1]<<".\n\n";
			CloseHandle(hSemaphore);
		 }
		 else
		 {
			cout<<"Ошибка создания семофора\n";
		 }
	}

	system("pause");
	return nRetCode;
}


void Test1(void *)
{
	cout<<"Тест 1 Запуск\n";
	DWORD dwWaitResult; 
	do
	{
		dwWaitResult = WaitForSingleObject(hSemaphore,100);
		Mas[1]=1;
		cout<<"Тест 1 TIMEOUT\n";
	}
	while(dwWaitResult==WAIT_OBJECT_0);
	Sleep(1000);
	if (ReleaseSemaphore(hSemaphore,1,NULL))
	cout<<"\nТест 1 Завершен.";
	_endthread();
}

void Test2(void *)
{
	DWORD dwWaitResult;
	cout<<"Тест 2 Запуск\n";
	do
	{
		dwWaitResult = WaitForSingleObject(hSemaphore,100);
		Mas[1]=2;
		cout<<"Тест 2 TIMEOUT\n";
	}
	while(dwWaitResult==WAIT_OBJECT_0);
	Sleep(1000);
	if (ReleaseSemaphore(hSemaphore,1,NULL))
	cout<<"\nТест 2 Завершен.";
	_endthread();
}

void Test3(void *)
{
	cout<<"Тест 3 Запуск\n";
	DWORD dwWaitResult; 
	do
	{
		dwWaitResult = WaitForSingleObject(hSemaphore,100);
		Mas[1]=3;
		cout<<"Тест 3 TIMEOUT\n";
	}
	while(dwWaitResult==WAIT_OBJECT_0);
	Sleep(1000);
	if (ReleaseSemaphore(hSemaphore,1,NULL))
	cout<<"\nТест 3 Завершен.";
	_endthread();
}

void Test4(void *)
{
	cout<<"Тест 4 Запуск\n";
	DWORD dwWaitResult; 
	do
	{
		dwWaitResult = WaitForSingleObject(hSemaphore,100);
		Mas[1]=4;
		cout<<"Тест 4 TIMEOUT\n";
	}
	while(dwWaitResult==WAIT_OBJECT_0);
	Sleep(1000);
	if (ReleaseSemaphore(hSemaphore,1,NULL))
	cout<<"\nТест 4 Завершен.";
	_endthread();
}
То, сначала у первого потока будет доступ к массиву 100мс, затем у второго 100мс, затем у третьего 100мс, затем первый поток закроется, откроется 4 поток и так же получит доступ к массиву на 100мс?
А через 1000мс после запуска каждый из потоков закрывается.

cMax - это как я понимаю начальное состояние счетчика и максимальное количество обращений, т.е. количество одновременно запущенных потоков?

Если все так, то по идее значение Mas[1] должно быть равно номеру последнего завершенного потока, т.е. на примере:

Цитата:
Тест 1 Запуск
Тест 2 Запуск
Тест 2 TIMEOUT
Тест 2 TIMEOUT
Тест 1 TIMEOUT
Тест 3 Запуск
Тест 4 Запуск
Тест 2 TIMEOUT
Тест 1 TIMEOUT
Тест 3 TIMEOUT
Тест 4 TIMEOUT

Тест 2 Завершен.
Тест 1 Завершен.
Тест 3 Завершен.

Последний доступ к массиву у потока 4.
Немного не понятно, почему Тест 2 завершается до Тест 1 и почему Тест 4 вообще не завершается.

Последний раз редактировалось ZBEP; 10.03.2011 в 23:04.
ZBEP вне форума Ответить с цитированием
Старый 11.03.2011, 00:20   #8
counter
Участник клуба
 
Регистрация: 18.10.2008
Сообщений: 1,409
По умолчанию

Цитата:
Сообщение от ZBEP Посмотреть сообщение
То, сначала у первого потока будет доступ к массиву 100мс, затем у второго 100мс, затем у третьего 100мс, затем первый поток закроется, откроется 4 поток и так же получит доступ к массиву на 100мс?
А через 1000мс после запуска каждый из потоков закрывается.
эм... нет! не факт, что менеджер процессов будет распределять процессорное время между потоками в порядке их запуска...
Цитата:
Сообщение от ZBEP Посмотреть сообщение
cMax - это как я понимаю начальное состояние счетчика и максимальное количество обращений, т.е. количество одновременно запущенных потоков?
http://msdn.microsoft.com/en-us/libr...38(VS.85).aspx


ps. код у вас стремный какой-то, и заданию не соответствует
counter вне форума Ответить с цитированием
Старый 11.03.2011, 00:25   #9
ZBEP
Форумчанин
 
Аватар для ZBEP
 
Регистрация: 23.03.2009
Сообщений: 334
По умолчанию

counter, ну то что не обязательно по порядку, это понятно (то я так для примера), а сам принцип выполнения я правильно уловил?
С cMax все понятно вроде.
И еще, на счет завершения последнего потока, почему он не завершается?

Цитата:
ps. код у вас стремный какой-то, и заданию не соответствует
Ну вот изначальный код задания:
Код:
#include "stdafx.h"
#include "windows.h"
#include "process.h" 

HANDLE hSemaphore;
LONG cMax = 2;
void Test1(void *);
void Test2(void *);
void Test3(void *);

CWinApp theApp;
using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{setlocale(LC_CTYPE, "");
	int nRetCode = 0;

	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		cout<<"Критическая ошибка: неудачная инициализация MFC\n";
		nRetCode = 1;
	}
	else
	{
		hSemaphore = CreateSemaphore( 
		NULL,// нет атрибута
		cMax,// начальное состояние
		cMax,// максимальное состояние
		NULL// без имени
		);

		 if (!hSemaphore == NULL) 
		 {
			if (_beginthread(Test1,1024,NULL)==-1)
			cout<<"Ошибка потока\n";
			if (_beginthread(Test2,1024,NULL)==-1)
			cout<<"Ошибка потока\n";
			if (_beginthread(Test3,1024,NULL)==-1)
			cout<<"Ошибка потока\n";
			Sleep(2000);
			CloseHandle(hSemaphore);
		 }
		 else
		 {
			cout<<"Ошибка создания семофора\n";
		 }
	}

	system("pause");
	return nRetCode;
}


void Test1(void *)
{
	cout<<"Тест 1 Запуск\n";
	DWORD dwWaitResult; 
	do
	{
		dwWaitResult = WaitForSingleObject(hSemaphore,1);
		cout<<"Тест 1 TIMEOUT\n";
	}
	while(dwWaitResult==WAIT_OBJECT_0);
	Sleep(1000);
	if (ReleaseSemaphore(hSemaphore,1,NULL))
	cout<<"\nТест 1 Завершен.";
	_endthread();
}

void Test2(void *)
{
	DWORD dwWaitResult;
	cout<<"Тест 2 Запуск\n";
	do
	{
		dwWaitResult = WaitForSingleObject(hSemaphore,1);
		cout<<"Тест 2 TIMEOUT\n";
	}
	while(dwWaitResult==WAIT_OBJECT_0);
	Sleep(1000);
	if (ReleaseSemaphore(hSemaphore,1,NULL))
	cout<<"\nТест 2 Завершен.";
	_endthread();
}

void Test3(void *)
{
	DWORD dwWaitResult; 
	cout<<"Тест 3 Запуск\n";
	do
	{
		dwWaitResult = WaitForSingleObject(hSemaphore,1);
		cout<<"Тест 3 TIMEOUT\n";
	}
	while(dwWaitResult==WAIT_OBJECT_0);
	Sleep(1000);
	if (ReleaseSemaphore(hSemaphore,1,NULL))
	cout<<"\nТест 3 Завершен.";
	_endthread();
}
Само задание:
Цитата:
1. Создайте любой дополнительный тестовый поток и разрешите одновременный доступ к семафору трех потоков.
2. Создайте разделяемый ресурс в виде глобального массива типа int и обеспечьте при помощи семафоров, единовременный доступ к элементам массива только одного потока. Другие потоки должны дожидаться очереди для доступа к общему ресурсу.
П.с.
Сказали, свой код нельзя, нужно этот дополнять.
Доп описаловки тоже нету, вот и не понятно немного что да как..

Последний раз редактировалось ZBEP; 11.03.2011 в 00:43.
ZBEP вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск