Ключевые слова:log, lock, (найти похожие документы)
_ RU.LINUX (2:5077/15.22) __________________________________________ RU.LINUX _
From : Vladimir A. Butenko 2:5020/400 23 Dec 99 17:29:56
Subj : рассказ про неблокирующие логи
_______________________________________________________________________________
From: [email protected] (Vladimir A. Butenko)
In article <[email protected]>, [email protected] wrote:
> b> Hда. Еще раз скажу - про доступ к NTFS hard-link из-под Win32 я не знал
> b> :-(
>
> Давайте вы за это расскажете про неблокирующие логи Ж:)?
Да хрен ли про них рассказывать - там же все просто, как папирус.
Стандартный еgetter/putter с кольцевым буфером:
void VLog::log(int debugLevel,const char* format,.....) {
if(logLevel >= debugLevel) {
char buffer[LogLineLength];
// here you should compose the log line
size_t lLine = formLogLine(buffer,format,.....);
putLogLine(buffer,lLine);
}
}
А, блин, программирование же тут об"явлено офф-топиком. Так что мы словами :-)
putLogLine - стандартный путтер (почти): занимает семафорчик, смотрит,
сколько есть в циклическом буфере места. Если хватает - то кладет туда в
него сформированную строку, освобождает семафор, переводя в состояние
"fill". Если строка не влезает, пробует засунуть строку "***", если
предыдущая строк уже не была ***. Если ничего не влезает - ничего не
делает.
Отдельный тред, сидит в окопе на том семафоре, lockWhenCondition(fill).
Стандартный геттер: проснулся, увидел, сколько накидали в буфер, запомнил,
сколько есть, освободил тут же семафор (не трогая указателей), сбросил на
диск сформированный кусок цикл. буфера, занял семафор, передвинул
get-указатель. Если сравнялся с put-указателем (то есть все выгребли), то
освободили, переведя в состояние empty и встали опять на ожидание
lockWhenCondition(fill). Иначе - повторили цикл сброса.
Все остальное - важные, но детали. В конце 1997 - было обсуждение, в
relcom.talk, где я предлагал исполнить это все не на семафорах (которых в
какой-нибудь embedded может и не быть), а просто на одной атомарной
операции "+=". Кажется, там же я приводил и решение. Hа них у меня
работали эти логи в MacOS где никаких семафоров и никаких тредов нету. А в
Линухе (он-топик :-) - все делается элементарно именно на семафорчиках и
тредах. "Легко видеть", что максимально время задержки - это время
формирования и копирования строчки лога.
Если у Вас ситуация такая, что лучше подзадержать, чем не скинуть Лог, то надо
либо иметь семафор с состояниями "пусто", "есть и данные, и место" и
"местов нет". И возможностью вставать на ПАРУ состояний (или на
"Hе-состояние"). Тогда перед переносом строки в буфер ставится не простой
lock(), а lockWhenCondition(Empty | HasSomeData) - это может
притормаживать.
--
Vladimir Butenko
Stalker Software, Inc.
--- ifmail v.2.14dev3 * Origin: Stalker Software, Inc. (2:5020/400)