Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> логирование в файл 
:(
    Опции темы
stan90
Дата 14.9.2011, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 12.11.2009

Репутация: нет
Всего: нет



здравствуйте.надеюсь что правильно выбрал раздел..
проблема в следующем.
есть задание :
Реализовать класс логирования в файлы.
Класс должен отвечать следующим требованиям:
1) Потокобезопасность (возможность работы с одним экземпляром класса из разных потоков)
2) Асинхронная запись логов. (Запись логов не должна приводить к блокированию потоков, которые используют объект класса логов, вне зависимости от объемов информации записываемой на жесткий диск).

В классе должны присутствовать публичные методы
Initialize(std::string filePath); (возможно использование конструктора).
WriteLog(std::string logLine); - основная рабочая функция класса, которая будет вызываться из других объектов/потоков.

Задание должно быть реализованно на C++ с использованием STL в среде Microsoft Visual Studio (либо в любой другой, но без использования спецефических компонентов среды).
Сторонние библиотеки в реализации применять не следует.

вот то что я сделал:
Код

using namespace std;

CRITICAL_SECTION cs;

ofstream file("test.txt");

class Logger
{
std::string filePath;
deque<string> queue;//либо это должен быть вектор
//static bool STOP;
public:
Logger()
//(std::string filePath)
{
//this->filePath = filePath;
//STOP = false;
InitializeCriticalSection( &cs );
_beginthread( Thread, 0, NULL );
}
~Logger(){}
static void Thread( void* pParams )
{
while ( TRUE )
{
EnterCriticalSection( &cs );
//string data=queue.pop_front();//здесь что-то подобное должно быть,но я не знаю точно как правильно.
LeaveCriticalSection( &cs );
file<<data;
}
}

void addData(string str)
{
while( TRUE )
{
EnterCriticalSection( &cs );
queue.push_back(str);
LeaveCriticalSection( &cs );
file<<str;
}
}
};

void main()
{ 
//Logger logger(С:\\test.txt");//не понятно как еще работает такая вещь
Logger logger;
logger.addData("data ");

}


вот что есть,но работает не совсем правильно,а точнее совсем видимо не правильно. C STL только-только начал знакомиться,моя первая программа.
буду признателен за любую помощь и подсказки

Это сообщение отредактировал(а) stan90 - 14.9.2011, 23:35
PM MAIL   Вверх
GremlinProg
Дата 15.9.2011, 06:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(stan90 @  15.9.2011,  01:27 Найти цитируемый пост)
Запись логов не должна приводить к блокированию потоков, которые используют объект класса логов, вне зависимости от объемов информации записываемой на жесткий диск

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

в твоем случае надо реализовать сигнальную модель: поток логгера спит, пока не активируется семафор hWake, после чего, он блокирует очередь, выбирает первую строку, пишет ее в файл и снова уходит в спячку,

выглядит это примерно так:
Код

while( ... ){
  ::WaitForSingleObject( hWake, INFINITE );
  Enter( ... );
  str = queue.front();
  queue.erase( queue.begin() );
  Leave( ... );
  file<<str;
}

а addData выглядит примерно так:
Код

void addData(string str){
  Enter( ... );
  queue.push_back(str);
  Leave( ... );
  ::ReleaseSemaphore( hWake, 1, NULL );
}


Добавлено через 2 минуты и 5 секунд
Цитата(GremlinProg @  15.9.2011,  08:26 Найти цитируемый пост)
блокирует очередь, выбирая первую строку




--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
stan90
Дата 15.9.2011, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 12.11.2009

Репутация: нет
Всего: нет



а как тогда организовать второй поток?
и правильно ли будет выглядеть это,ведь функция статик значит доступ к вектору только через указатель?
Код

  
static void Thread( void* pParams )
{
Logger *p;
string str;
::WaitForSingleObject( hWake, INFINITE );
while ( TRUE )
{
EnterCriticalSection( &cs );
str = p->queue.front();
p->queue.erase( p->queue.begin() );
LeaveCriticalSection( &cs );
file<<str;
}
}


еще вопрос как работает путь к файлу,который в качестве параметра передается конструктору?разве недостаточно ofstream?
PM MAIL   Вверх
Earnest
Дата 15.9.2011, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Цитата(GremlinProg @  15.9.2011,  07:26 Найти цитируемый пост)
в твоем случае надо реализовать сигнальную модель: поток логгера спит, пока не активируется семафор hWake, после чего, он блокирует очередь, выбирает первую строку, пишет ее в файл и снова уходит в спячку,

Угу, только записывать лучше все, что насобиралось в очереди, а не только одну строку. Хотя чаще всего она там одна и будет.
Я такую штуку делала, для синхронизации использовала сочетание событие + критическая секция (для собственно блокировки).
Просто обернула стандартную очередь stl. Плюс еще доп. класс Inserter, для реализации "потокового" вывода (т.е. через оператор <<) - stl так stl!
Еще полезно к логу приделать UnhandledExceptionFilter, это позволяет протоколировать почти все падения.


--------------------
...
PM   Вверх
GremlinProg
Дата 16.9.2011, 06:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(stan90 @  15.9.2011,  17:09 Найти цитируемый пост)
а как тогда организовать второй поток?

поток, который использует Logger?
как угодно, экземпляр Logger'а можно сделать статиком, например, тогда он будет доступен из любого потока
Цитата(stan90 @  15.9.2011,  17:09 Найти цитируемый пост)
и правильно ли будет выглядеть это,ведь функция статик значит доступ к вектору только через указатель?

если доступ через указатель, это еще не значит, что код стал потоконебезопасным, 
потокобезопасным он стал как только были установлены и соблюдены правила синхронизации доступа к данным,
а доступ к ним можно осуществлять как душе угодно, хоть словесно )

кстати, последный код неверный, смотри внимательнее на то, где расположен WaitForSingleObject
Цитата(Earnest @  15.9.2011,  17:11 Найти цитируемый пост)
только записывать лучше все, что насобиралось в очереди, а не только одну строку

тогда будет нарушено равновесие:
в данном случае, в качестве счетчика строк выступает семафор, т.е. на каждую строку его надо разрядить, иначе будут лишне срабатывания,
в твоем случае, на стороне потока можно завести некоторый буфер, куда копить пару секунд ( макс. задержка выбирается опционально ) строки,
если по их истечении семафор ни разу не сработает, можно писать его в файл и очищать

Это сообщение отредактировал(а) GremlinProg - 16.9.2011, 06:16


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
stan90
Дата 16.9.2011, 09:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 12.11.2009

Репутация: нет
Всего: нет



спасибо.попробую.

а как быть с этим : как работает путь к файлу,который в качестве параметра передается конструктору?разве недостаточно ofstream? 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0489 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.