LINUX.ORG.RU

Линукс и реальное время или почему fflush не работает как надо


0

0
В очередной раз пишу не надеясь получить ответа на вопрос, но для очестки совести. Рассказывали, что ОС реального времени - эта та, время реакции которой прогнозируемо. Отлично. Тогда скока же времени нужно линуксу, чтобы записать на жёсткий диск 1 мегабайт ? Не спешите с ответами. Сначала давайте-ка напишем программку, которая раз в 50 миллисекунд валит в файл на диск информацию порциями по 1000000 байт. В программе посчитаем, скока нужно линуксу времени для этого. А получается вот что : в большинстве случаев времени для этого линуксу надо довольно мало, но периодиски мы имеем что линуксу для записи 1 мегабайта на диск надо 300-2000 миллисекунд ! И всё бы было объяснимо и понятно, кеширование там и всё такое, если бы не одна деталька : после записи информации мы используем функцию fflush, которая обязана содержимое буферов сбросить на диск. Что же это за взбрыкивания такие, а, дорогие товарищи ? Какова их природа, объясните пжлста, если можете. Текст програмы приведу ниже.

# include <sys/timeb.h>
# include <stdio.h>
# include <time.h>
# include <sys/time.h>


__inline__ unsigned long long int rdtsc()
{
	unsigned long long int x;
	__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
	return x;
}

unsigned long long GetCurrentTime(void)
{
	static struct timeb tt;
	unsigned long long result;
	
	static struct timeval ttt;
	struct timezone tz;
	unsigned long long int r;
	
	ftime(&tt);
	
	int rv;
	
	rv = gettimeofday(&ttt, &tz);
	
	
	r = rdtsc();
	
	result=(unsigned long long)((unsigned long long)ttt.tv_sec/*time(&unused)*/ * (unsigned long long)1000000)+(unsigned long long)ttt.tv_usec;
	
	return result;
}

/* миллисекунд */
void usleep_my (unsigned int ms)
{
	struct timespec req;
	
	
	if (!ms) return;
	
	req.tv_sec=ms/1000;
	req.tv_nsec=(ms-req.tv_sec*1000)*1000000;
	
	nanosleep(&req, NULL);
}

int main (void)
{
# define SIZEOFBUFFER 1000000
	char buffer [SIZEOFBUFFER];
	unsigned long long t1, t2;	
	
	FILE * fil;
	
	
	fil = fopen("test.null", "a");
	
	while (1)
	{
		usleep_my(50);
		
		t1 = GetCurrentTime();
		
		fwrite (buffer, SIZEOFBUFFER, 1,  fil);
		fflush (fil);
		
		t2 = GetCurrentTime();
		
		printf ("%2.1f \n", (double)(t2-t1));
		
		t1 = t2;
	}
}
lenin
() автор топика
Ответ на: комментарий от lenin
Наблюдать за программой минутку-две.
lenin
() автор топика
Ответ на: комментарий от alexru
Какой патч посоветуете ? Можно ли отключить кеширование данных ? Нужно чтобы сразу сбрасывались, как в чистой ДОС.
lenin
() автор топика
Ответ на: комментарий от lenin
А если добавть sync(); , то всё ок:)
anonymous
()
Ответ на: комментарий от lenin
Иди-ка ты почитай man fflush для начала, прежде чем в очередной раз всякую фигню сюда писать.

fflush НЕ СБРАСЫВАЕТ буфера на диск, задача fflush в том, чтобы выполнить системный вызов write для буфера потока (FILE *), находящегося в пространстве пользователя.

anonymous
()
Ответ на: комментарий от lenin
Чтобы сбрасывалось сразу на диск нужно добавить при его монтировании опцию sync.
alexru ★★★★
()
>ассказывали, что ОС реального времени - эта та, время реакции которой ?

каким боком относиться linux к ОС жесткого реального времени?
fghj ★★★★★
()
Ответ на: комментарий от fghj
ты всё испортил: теперь Россия не выполнит свои обязательства по экспорту сероводорода :)
Pi ★★★★★
()
Ответ на: комментарий от lenin
> Можно ли отключить кеширование данных ? Нужно чтобы сразу сбрасывались, как в чистой ДОС.

Блин, троллюга недобитая... Прочти man 2 open ВНИМАТЕЛЬНО на предмет опции O_SYNC. В сщчетании с fflush это даст запрошеный тобой эффект.

no-dashi ★★★★★
()
Ответ на: комментарий от no-dashi
И еще - если тебе нужен именно FILE * для fprintf, fputs и так далее на синхронных операциях, используй open + fdopen + setvbuf.
no-dashi ★★★★★
()
man fsync
man fdatasync
сначала fflush, потом fdatasync, только после этого долетят изменения до диска.
Casus ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.