我已经尝试并尝试在 SO 和整个 Internet 上找到关于此的预先存在的讨论。也许我做得不对,因为很难相信基本 C 语言没有解决这个问题。
我有一些计算简单的代码,但需要执行大量日志记录。此日志记录当前使我的代码运行速度慢了 10 倍。显然,解决方案是将日志记录中断到一个单独的线程或进程中。使用单独的进程需要大量特定于平台的 mumbo-jumbo,我需要此代码尽可能保持可移植性(目前在 OS X 中开发,稍后将移植到 Windows)。所以我刚刚开始学习线程和pthread.h。
需要明确的是,与 Internet 上一些现有的 pthread 讨论不同,我们在这里讨论的是直接写入文件,而不是 I/O。程序永远不需要读取日志文件。我现在正在做的是:
/* Called many times a second; a few minutes of program usage will make
a couple megs of text in the log file */
void MyLogFunction(char *format, ...)
{
char buffer[1024];
va_list arglist;
va_start(arglist, format);
vsnprintf(buffer, sizeof(buffer) - 1, format, arglist);
va_end(arglist);
pthread_t threadID;
pthread_create(&threadID, NULL, WriteLog, &buffer);
}
/* As written, this function writes unpredictable contents to disk because
I passed it a pointer to a local variable that is getting modified
constantly by the main thread; I know I should be doing something like
allocating new blocks of memory within MyLogFunction() for each pthread,
so let's pretend I'm doing that and move on with the discussion ;-) */
void *WriteLog(void *string)
{
pthread_detach(pthread_self());
fprintf(gLogHandle, "%s: %s\n",
/* OS X time-to-string stuff omitted here */,
(char *)string);
fflush(gLogHandle);
return NULL;
}
我担心两件事:
A. 每秒产生多达几十个 pthread 似乎是不明智的。是吗?
B. 消息有时可能会乱写,对吧?
这导致我提出以下三个问题:
我应该创建一个保持打开状态的日志记录线程吗?它怎么知道什么时候写另一行而不快速轮询?我不能悠闲地轮询一些
gNewLineIsAvailableToWrite
布尔值,因为这段代码有时会崩溃,而且我不能错过崩溃前的最后一条日志消息。此外,日志中新行的创建每隔几个滴答就会达到峰值,每个滴答可能有 20 行。我是否应该像当前显示的那样制作单独的 pthread,但给他们彼此的 ID 并告诉他们,
pthread_join()
以便他们在写他们的行之前等待前一个线程完成?这仍然会导致线程激增,但至少它们会按顺序写入,嗯?还是我看这个问题都错了?