Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在多线程应用程序中将日志写入文件_C_Multithreading_Logging - Fatal编程技术网

C 在多线程应用程序中将日志写入文件

C 在多线程应用程序中将日志写入文件,c,multithreading,logging,C,Multithreading,Logging,我已经编写了一个服务器客户端应用程序。现在,我必须将服务器上发生的事情写入日志文件。服务器是用C写的。我已经可以用printf写屏幕上发生的事情了 所以我只能使用fprintf而不是printf。我的问题是我应该如何处理这个文件 我有Server.c源文件,其中有主函数 以下是我的服务器应用程序的基本结构: 服务器.c handle_client是一个在新线程中处理客户端的函数 如何创建服务器日志?我将有一个文本文件,例如SERVERLOG.log,但服务器上有许多客户端。我应该如何处理对此文件

我已经编写了一个服务器客户端应用程序。现在,我必须将服务器上发生的事情写入日志文件。服务器是用C写的。我已经可以用printf写屏幕上发生的事情了

所以我只能使用fprintf而不是printf。我的问题是我应该如何处理这个文件

我有Server.c源文件,其中有主函数

以下是我的服务器应用程序的基本结构:

服务器.c

handle_client是一个在新线程中处理客户端的函数

如何创建服务器日志?我将有一个文本文件,例如SERVERLOG.log,但服务器上有许多客户端。我应该如何处理对此文件的多重访问

一种方法是在启动服务器、打开、写入、关闭时创建文件。 如果客户机希望写入文件,则应打开该文件进行写入,然后关闭该文件


但是,当更多的客户端希望写入此文件时,仍然存在一个问题。…

请将其保持打开状态。在服务器启动时打开日志文件。

常见的解决方案是使用类似printf的函数,该函数首先将所有输出写入缓冲区,然后锁定信号量,对文件进行实际写入,然后解锁信号量。如果您担心实际写入速度慢,您可以使用一个队列插入所有日志消息,并让另一个线程从队列中取出项目并将其写入文件,您仍然需要使用信号灯等来保护队列,但这样做应该比I/O更快


对于实际文件,要么在主线程中打开它,要么让它保持打开状态。或者,如果您有一个带有队列的特殊日志线程,则让该线程执行打开操作。无论如何,您不必在每次写入内容时都不断地打开/关闭它,重要的是防止多个线程同时写入它。

避免输出缓冲区严重交错的一个简单方法是使用单独的日志记录过程,由管道或命名管道连接。记录器只是被阻塞在从管道读取的数据上,并将它得到的任何数据写入文件。读卡器的stdin、stdout实际上可以指向管道和客户机刚刚写入管道的文件,这些文件可以通过stderr复制到管道上。写入管道到管道的操作保证是原子的。

Thx,对我来说,处理客户机唯一使用的线程是可怕的enouht。因此,我可能会将第一个建议用于信号量,而不是处理另一个线程。。但是我对你的第一条建议还有一个问题——关于缓冲区,如果信号量被锁定怎么办?它已经在那个缓冲区中了?@user1097772如果你只保留一个像char buffer[256]这样的局部变量,那么它实际上是线程的局部变量。如果信号量被锁定,您可以放弃消息,等待一段时间再放弃消息,或者等待线程轮到您,或者您可以使用现有的类似printf的函数,因为它们已经这样做了。请看下面的说明,所有引用FILE*对象的函数的行为都应该像它们在内部使用flockfile和funlockfile一样,以获得这些FILE*对象的所有权。@DavidSchwartz即使这样,也可能不是所有库都能实现它。我个人看到printf和fprintf从不同的线程到同一个文件会把事情搞得一团糟,在VC++中也是如此。我知道这有点晚了,但我已经编辑了你的问题。即使你的英语不是很好,你所能做的最简单的努力就是在任何文本处理器中复制粘贴并修复这些简单的错误,即使浏览器也提供了这些。
//.. 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