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

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

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 28.06.2013, 11:09   #1
denrubun
Пользователь
 
Регистрация: 24.12.2012
Сообщений: 82
По умолчанию Потоки, синхронизация, простой

Уважаемые форумчане, нужна ваша помощь!

есть вот такая функция для потока:

Код:
DWORD WINAPI event_engine::main_loop(LPVOID x){
	event_engine *t = (event_engine *)x;
	event_queue::event_iter cur, end = t->_events.end();
	while(true){
		cur = t -> _events.begin();
		if(cur == end){  //события закончились, остановка
			cout << "event_queue is empty. thread stopped\n";
			t->stop();
		}
		else if(t->getCurTime() >= (*cur)->gettime()){	  //событие должно произойти
			
			EnterCriticalSection( &(t->_crt) );

			(*cur)->happen();  //происходит
			t->_events.pop_front();  //удаляется
			
			LeaveCriticalSection( &(t->_crt) );
		}
		else{	  //события есть, но еще не время
			t->setstate(Waiting);
			cout << "_state set to 'Waiting'. thread paused\n";
			//Sleep( (*cur)->gettime() - t->getCurTime());	  //ждем наступления первого события
		}
	}
	return 0;
};

занимается просмотром событий в очереди и выполнением их, если время настало.

если события кончились, останавливает поток, а добавление нового события его снова запустит.

а если событие не наступило, его надо подождать.
Вопрос в ток как это сделать:

если повесить Sleep, тогда при добавлении нового события, которое должно случиться раньше первого(на момент Sleep'а)
поток продолжит спать, и выполнится не раньше намеченного времени.

а если ничего не сделать цикл будет вхолостую крутиться и подъедать ресурсы, но работать будет правильно.

есть какой-нибудь аналог слипа, который можно разбудить?
denrubun вне форума Ответить с цитированием
Старый 28.06.2013, 12:12   #2
counter
Участник клуба
 
Регистрация: 18.10.2008
Сообщений: 1,409
По умолчанию

SuspendThread \ ResumeThread

WaitForsingleObject \ WaitForMultipleObjects
counter вне форума Ответить с цитированием
Старый 28.06.2013, 13:22   #3
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Прочитайте про семафоры.
waleri вне форума Ответить с цитированием
Старый 28.06.2013, 16:50   #4
denrubun
Пользователь
 
Регистрация: 24.12.2012
Сообщений: 82
По умолчанию

если я заюзаю SuspendThread:
если за время простоя добавится новое событие в начало очереди, то все ок.
но если события не добавится, кто разбудит поток во время наступления первого события?

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

=======================

есть вариант Sleep(50) ,например. будет проверять каждые 50 миллисекунд, все лучше чем постоянно крутиться.

и все же хотелось бы что-то вроде SuspendThread, только еще с параметром времени, как в WaitForSingleObject, но как это сделать, я пока не знаю

Последний раз редактировалось denrubun; 28.06.2013 в 16:52.
denrubun вне форума Ответить с цитированием
Старый 28.06.2013, 18:26   #5
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Каждый, кто добавит в очередь будет вызвать ResumeThread(), после извлечения и выполнения каждого елемента из очереди рабочий поток будет вызывать SuspendThread(). При создании рабочега потока сразу вызываем SuspendThread() (или прямо создаем поток спящим).

Одно непонятно - зачем изобретать колесо а не прочитать про семафоры?
Далее, почему нельзя использовать WaitForSingleObject но можно использоват ResumeThread, Sleep, etc?

Зачем вообще нужен параметр времени? Это когда используем Sleep, только Sleep очень вредная функция...
waleri вне форума Ответить с цитированием
Старый 29.06.2013, 10:06   #6
denrubun
Пользователь
 
Регистрация: 24.12.2012
Сообщений: 82
По умолчанию

Цитата:
Каждый, кто добавит в очередь будет вызвать ResumeThread(), после извлечения и выполнения каждого элемента из очереди рабочий поток будет вызывать SuspendThread(). При создании рабочего потока сразу вызываем SuspendThread() (или прямо создаем поток спящим).
все правильно поняли. Или у вас есть претензии к такому подходу?


Цитата:
Далее, почему нельзя использовать WaitForSingleObject но можно использовать ResumeThread, Sleep, etc?
не нельзя, просто я не знаю как. Ведь она ожидает дескриптора ресурса, который может сигнализировать о состоянии, а у меня только мой простой класс.
Или вы предлагаете дополнить/заменить его?
Мой класс Event является базовым для всех событий в игре, он никак не связан с библиотечным, вообще никак.

Код:
class Event{
protected:
	time_t _time;
public:
	Event(){
		_time = GetTickCount() / (float)CLOCKS_PER_SEC * 1000;
	};

	Event(const time_t &timeDelta) {
		_time = GetTickCount() / (float)CLOCKS_PER_SEC * 1000 + timeDelta;
	};

	bool operator<(const Event &other){
		return (_time < other._time);
	};

	bool operator==(const Event &other){
		return (_time == other._time);
	};

	virtual void happen() {
		cout << "event happened at " << GetTickCount() << "\n\n";
	};
	time_t gettime() const {
		return _time;
	};
};
Цитата:
только Sleep очень вредная функция...
почему?

из вики:
Код:
Семафо́р — объект, позволяющий войти в заданный участок кода не более чем n потокам. Определение введено Эдсгером Дейкстрой.
Семафоры используются при передаче данных через разделяемую память.
ну так у меня не в семафорах проблема, и не в совместном доступе, а в том как мне правильно организовать ожидание. Или я не понял вашей мысли?
denrubun вне форума Ответить с цитированием
Старый 29.06.2013, 10:32   #7
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Цитата:
Сообщение от denrubun Посмотреть сообщение
Или у вас есть претензии к такому подходу?
Мне по барабану.

Цитата:
Сообщение от denrubun Посмотреть сообщение
а в том как мне правильно организовать ожидание.
Ожидание делается через функции ожидания - WaitForSingleObject() о чем вам сказали в первом же ответе.
CreateEvent(), SetEvent(), WaitForSingleObject() - для одного потока этого вполне достаточно.
Если надо несколько рабочих потоков (что лучше) то лучше использовать семафоры. Нет, можно сделать тем же SetEvent() но надо будет изобретать велосипед.
waleri вне форума Ответить с цитированием
Старый 29.06.2013, 10:54   #8
denrubun
Пользователь
 
Регистрация: 24.12.2012
Сообщений: 82
По умолчанию

т.е. мне нужно создать событие с помощью CreateEvent() и повесить ожидание этого события с помощью WaitForSingleObject().
тогда нужно в нужное время чтобы это событие отсигналило и ожидание прекратилось.
т.е. таки прикрутить к этому еще таймер?
denrubun вне форума Ответить с цитированием
Старый 29.06.2013, 11:05   #9
counter
Участник клуба
 
Регистрация: 18.10.2008
Сообщений: 1,409
По умолчанию

Цитата:
Сообщение от denrubun Посмотреть сообщение
не нельзя, просто я не знаю как. Ведь она ожидает дескриптора ресурса, который может сигнализировать о состоянии, а у меня только мой простой класс.
Или вы предлагаете дополнить/заменить его?
Мой класс Event является базовым для всех событий в игре, он никак не связан с библиотечным, вообще никак.
Что Вам мешает дополнить свой класс до состояния стандартного Event'а ?
К тому же можно в Wait-функцию передать дескриптор вашего объекта, после его разрушения функция вернет управление.

Еще есть такие вещи как таймеры ожидания и условные переменные:
Waitable Timer
Condition Variables
counter вне форума Ответить с цитированием
Старый 29.06.2013, 11:16   #10
denrubun
Пользователь
 
Регистрация: 24.12.2012
Сообщений: 82
По умолчанию

Спасибо, думаю вопрос решен!
denrubun вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
синхронизация s.e.r.g. C++ Builder 10 11.02.2013 22:33
Синхронизация БД Bright-rider БД в Delphi 3 19.06.2012 07:32
Синхронизация tesseract Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 2 20.03.2012 10:31
Синхронизация kostyan142 Общие вопросы по Java, Java SE, Kotlin 6 13.01.2010 01:39
Синхронизация yarilo Софт 2 07.08.2009 15:50