Запись логов в файл в многопоточном приложении - PullRequest
0 голосов
/ 07 марта 2012

Я написал сервер-клиентское приложение. Теперь я должен записать, что происходит на сервере, в файл журнала. Сервер написан на C. Я уже могу написать, что происходит с экраном, используя printf.

Так что мне просто нужно использовать fprintf вместо printf. У меня вопрос, как мне обращаться с файлом?

У меня есть Server.c исходный файл, в котором есть основная функция

Вот основная структура моего Серверного приложения:

Server.c

//.. some code 
int main(...) {
//some code
//initialize variables
//bind server
//listen server on port
  while(1) 
  {
  //accept client

  int check = pthread_create(&thread, NULL, handle_client,&ctx);//create new thread

  //..
  }//end while
return EXIT_SUCCESS;
}//end main

handle_client - это функция, которая обрабатывает клиентов в новом потоке.

Как мне сделать журнал сервера? У меня будет один текстовый файл, например SERVERLOG.log, но на сервере много клиентов. Как мне обрабатывать множественный доступ к этому файлу?

Один из способов - создать файл при запуске сервера, открыть его, написать в нем, закрыть его. Если клиент хочет записать в файл, он должен открыть файл, чтобы записать в него, а затем закрыть его.

Но по-прежнему существует проблема, когда больше клиентов хотят писать в этот файл ....

Ответы [ 3 ]

3 голосов
/ 07 марта 2012

Распространенное решение состоит в том, чтобы иметь printf -подобную функцию, которая сначала записывает весь вывод в буфер, затем блокирует семафор, выполняет фактическую запись в файл и разблокирует семафор.Если вас беспокоит, что фактическая запись идет медленно, вместо этого вы можете создать очередь, в которую вставляются все сообщения журнала, и позволить другому потоку взять элементы из очереди и записать их в файл, вам все равно придется защищать очередь, напримерсемафор, но это должно быть быстрее, чем делать ввод / вывод.

Что касается самого файла, либо откройте его в главном потоке, и оставьте его открытым.Или, если у вас есть специальный поток регистрации с очередью, то пусть этот поток делает открытие.В любом случае, вам не нужно открывать / закрывать его каждый раз, когда вы хотите что-то записать, важная часть - защитить его от одновременной записи в несколько потоков.

0 голосов
/ 07 марта 2012

Простой способ избежать плохо чересстрочных выходных буферов - использовать отдельный процесс регистрации, связанный с каналом (или именованным каналом). Регистратор просто блокируется на чтение () из канала и записывает все, что он получает в файл. (stdin читателя, stdout может фактически указывать на канал и файл) Клиенты просто записывают в канал (который может быть dup () d over stderr) Запись в канал (до PIPE_BUF) гарантированно будет атомарной. 1001 *

0 голосов
/ 07 марта 2012

Просто оставь это открытым.Откройте файл журнала при запуске сервера.

...