多个线程/进程共享标准输出

6

我有一个Linux程序(语言不重要),它将日志打印到标准输出中。

为了监控进程,需要这个日志。

现在我要通过fork或使用线程并行化它。

问题是:结果的标准输出将包含混杂的无关行……

最后问题是:你会如何重新构建并行进程的输出逻辑?


你想将日志拆分为单独的进程/线程日志,还是只想避免在一行中混合来自多个进程的输出? - lanzz
它应该在视觉上按进程分离。这样用户就可以了解每个任务的状态。原子行只是一个小问题,我将使用一些同步对象。 - LiMar
2
为每个进程打上独特的标记,例如[process-$PID][roleOfTheProcess],以便在日志中进行区分? - lanzz
+1 作为可能的方法之一...仍在寻找将输出分离成每个进程的子日志的方法。 - LiMar
1
您可以对日志进行标记,随后可以按标记过滤到子日志中。 - lanzz
4个回答

3

非常抱歉自问自答...

明确的解决方案是使用GNU parallel工具。

它取代了众所周知的xargs工具,但可以并行运行命令,将输出分成组。

所以我只需保留我的简单单进程、单线程工具不变,并将其调用通过parallel管道传递,就像这样:

generate-argument-list | parallel < options > my-utility

这取决于parallel的选项,可以为多个调用my-utility产生漂亮的分组输出。


3
另一种我们使用的方法是委派一个线程,即记录器线程,用于记录日志。所有其他希望记录日志的线程都会将其发送到记录器线程。此方法具有灵活性,因为可以在单个位置进行日志格式化,这也可以进行配置。如果您不想担心锁问题,可以使用套接字进行消息传递。

2
如果它是多线程的,则需要使用互斥锁保护对标准输出日志的打印/写入。在Linux和c/c++中,最常用的方法是使用pthread_mutex。另外,如果是c++,boost有可以使用的同步机制。
为了实现它,您应该将所有日志记录封装在一个函数或对象中,并在内部锁定和解锁互斥锁。
如果日志记录阻塞性能成为问题,您可以考虑在缓冲区满时(在上述对象或函数中)缓冲日志消息并仅写入stdout。您仍然需要互斥保护来进行缓冲,但缓冲比写入stdout更快。
如果每个线程都有自己的日志记录消息,则它们仍然需要共享相同的互斥锁以便写入stdout。在这种情况下,最好让每个线程缓冲其各自的日志消息,并仅在缓冲区满时写入stdout,从而仅获取用于写入stdout的互斥锁。

2
如果您使用的是C ++,我建议使用Pantheios或其衍生版本Boost :: Log,或者查看Logging In C ++:Part 2
如果您使用的是其他语言,则文件锁定可能是围绕IO操作的最佳方式,请参见File Locks。您可以使用信号量或任何其他进程控制系统来实现相同的结果,但对于我来说,文件锁定是最简单的方法。
如果此监视被视为系统范围,则还可以考虑使用syslog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接