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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 14.07.2010, 08:19   #1
Teksa
Пользователь
 
Регистрация: 24.08.2007
Сообщений: 88
По умолчанию Sleep(50); за 63 мс... или за 47...

Здравствуйте . Есть клиент, сервер, сервер обрабатывает данные приходящие от клиентов и отсылает результат, результат должен отсылаться строго каждые 50 мс. Что я делаю:
1)- измеряю время обработки (clock_t start = clock()... обработка...clock_t finish = clock() ).
2) - после обработки стоит Sleep(50+start-finish)

в результате кадры отсылаются каждые 63 мс...
Дебаг показал что старт равен финишу, добавил еще одну временную метку после Sleep, оказалось что слип(50) длится до 63 мс.. приложение многопоточное, ось -Windows.

В качестве эксперимента была выкинута обработка и прочие ненужные вещи остался голый слип(50) который все равно умудряется тянутся до 63 мс... как бы поточнее?
Код:
 clock_t startcalc,allfinish,finishcalc;

	while (serv->m_ContinueCicl)
	{
		startcalc=clock();

//когда то здесь планировалось обрабатывать данные

		finishcalc= clock();
		
		//пакеты по 50 миллисекунд
		Sleep(50);//+startcalc-finishcalc);

		allfinish =clock();
			
			

				double d=((double)(finishcalc-startcalc))/CLOCKS_PER_SEC;	
				double ad=((double)(allfinish-startcalc))/CLOCKS_PER_SEC;
				
				printf("  calc done at %.6f	, sleep done at	%.6f , sleep %d\r",d,ad,allfinish-finishcalc);	
				if (ad>0.047) printf("\n");
Цитата:
calc done at 0.000000 , sleep done at 0.063000 , sleep 63
calc done at 0.000000 , sleep done at 0.062000 , sleep 62
calc done at 0.000000 , sleep done at 0.062000 , sleep 62
calc done at 0.000000 , sleep done at 0.062000 , sleep 62
calc done at 0.000000 , sleep done at 0.062000 , sleep 62
calc done at 0.000000 , sleep done at 0.063000 , sleep 63
calc done at 0.000000 , sleep done at 0.047000 , sleep 47
можно как нибудь отсылатся именно каждые 50 секунд? или каждые 47 ...

Последний раз редактировалось Teksa; 14.07.2010 в 09:36.
Teksa вне форума Ответить с цитированием
Старый 14.07.2010, 09:41   #2
ThisIzGame
Форумчанин
 
Регистрация: 31.08.2009
Сообщений: 161
По умолчанию

попробуйте функцию GetTickCount(void), впринципе она должна точно работать(точность не измерял, но читал, что она хорошо работает)...
пример использования:
Код:
// замеряем начальное время
DWORD start_time = GetTickCount();
// ...
while(GetTickCount() - start_time < 50);
// ...
ThisIzGame вне форума Ответить с цитированием
Старый 14.07.2010, 09:41   #3
RUSt88
Участник клуба
 
Регистрация: 29.12.2009
Сообщений: 1,166
По умолчанию

а если сделать посылку пакетов в таймере?
прогер C\C++\C#\Delphi
ася: [семь 3]-[97]-[1 шесть]
RUSt88 вне форума Ответить с цитированием
Старый 14.07.2010, 09:49   #4
Teksa
Пользователь
 
Регистрация: 24.08.2007
Сообщений: 88
По умолчанию

ГетТикКаунт сейчас попробую Почему то в голову не пришло, спасибо

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


Кстати есть мысль ориентироваться по прошлому кадру, то есть если в прошлой итерации кадр проспали на 13 мс , то в этом спать на те же 13 мс меньше..
Teksa вне форума Ответить с цитированием
Старый 14.07.2010, 09:52   #5
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

GetTickCount() не так уж хорошо работает. По моим приблизительным оценкам ее погрешность, равно как и разрешающая способность составляют порядка 10мс. Вообще, думаю, большинство таких функций работают немногим лучше, хотя не поручусь.
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 14.07.2010, 10:51   #6
Teksa
Пользователь
 
Регистрация: 24.08.2007
Сообщений: 88
По умолчанию

Цитата:
8378 delay: 0.047000, average delay 46.876820 , maxdelay = 63, mindelay = 46
- если использовать:

Код:
while (finishcalc-startcalc<45)
		{
			Sleep(5);
			finishcalc= GetTickCount();
		}
то же самое дает стабильное 47 мс макс задержки если убрать слип))) и забивать точным измерением времени весь проц/ядро
Teksa вне форума Ответить с цитированием
Старый 14.07.2010, 14:34   #7
evgn
Разрабатываюсь....
Пользователь
 
Регистрация: 16.11.2008
Сообщений: 68
По умолчанию

Попробуй использовать мультимедийный таймер:
Цитата:
#include <mmsystem.h>
timeSetEvent()
Или вот еще можно
Цитата:
QueryPerformanceFrequency(...);
QueryPerformanceCounter(...);
Пример:

Цитата:
void Wait(int time)
{
LARGE_INTEGER time_f, time_l, tps;
int tpms;
QueryPerformanceCounter(&time_f);
QueryPerformanceFrequency(&tps);
tpms = tps.QuadPart / 1000;
do
{
QueryPerformanceCounter(&time_l);
}while((time_l.QuadPart - time_f.QuadPart) / tpms < time);
}
Только процесс не будет спать в этом случае и будет грузить проц.
evgn вне форума Ответить с цитированием
Старый 15.07.2010, 22:37   #8
Oleg_SK
Пользователь
 
Регистрация: 06.06.2010
Сообщений: 42
По умолчанию

Цитата:
Сообщение от Teksa Посмотреть сообщение
можно как нибудь отсылатся именно каждые 50 секунд? или каждые 47 ...
AFAIK, этого сделать нельзя, т.к. ОС семейства Windows не относятся к операционным системам реального времени, и по этому не могут гарантировать выполнение каких-то действий в строго указанное время; всегда возможно какое-то отклонение... Даже если попытаться в цикле ждать нужного времени, как это предлагает evgn, может случиться так, что в нужное время процесс (точнее - нужный поток этого процесса) работающий по вашей программе будет не активным, и стоять в очереди ожидая очередного кванта процессорного времени на свое выполнение... Потом, когда он все же дождется своего времени, ОС может потребоваться сбросить в своп часть содержимого RAM, а затем подгрузить из свопа в RAM код и данные вашей программы; тут нужно вспомнить что операции со своп файлом (как и любые другие операции с HDD) идут относительно медленно. Подобным образом и возникают непредсказуемые задержки...

Последний раз редактировалось Oleg_SK; 15.07.2010 в 23:21.
Oleg_SK вне форума Ответить с цитированием
Старый 20.07.2010, 08:34   #9
Teksa
Пользователь
 
Регистрация: 24.08.2007
Сообщений: 88
По умолчанию

на системе реального времени подобный вопрос бы и не возник, тут и была вся проблема в этом) в принципе вопрос мог звучать как "способы компенсации неточности измерения времени в операционной системе Okna ".
кстати если не отдавать sleep ом управление - все более менее стабильно вопрос не решен а скорее обойден - добавил синхронизацию по времени между клиентами и сервером, соответсвенно загулявшие задержки и тд теперь отлавливаю по временной оси. Кстати большую точность чем Sleep(50) выдавал

Код:

LastTickCount =GetTickCount() ;
while (GetTickCount() - LastTickCount<50)
Sleep(5);
или что-то в этом роде

evgn спасибо timeSetEvent() оказывается полезная штука
Teksa вне форума Ответить с цитированием
Ответ


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

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
функция Sleep() ^Angel^ Общие вопросы C/C++ 9 07.05.2011 13:27
Функция Sleep(); VadEr Общие вопросы Delphi 6 10.09.2009 17:45
Проблема с Sleep! k1r1ch Общие вопросы Delphi 11 20.06.2009 19:12
Аналог Sleep() Ants Общие вопросы Delphi 2 18.11.2008 13:11
Альтернатива sleep Zuzlan Общие вопросы Delphi 2 01.11.2007 01:44