在多线程应用程序中控制对输出的访问
Posted
技术标签:
【中文标题】在多线程应用程序中控制对输出的访问【英文标题】:Controlling access to output in multi-threaded applications 【发布时间】:2010-01-04 00:12:37 【问题描述】:我有一个创建作业队列的应用程序,然后多个线程执行这些作业。通过执行它们,我的意思是它们使用作业字符串调用 system()。
问题是标准输出的输出看起来像问题底部的输出。我希望每个应用程序运行分开,所以输出看起来像:
弗拉克 1.2.1 ... ... ... 弗拉克 1.2.1 ... ... ... 等等我正在使用我无法控制的程序,因此无法将 IO 包装在互斥体中。
如何让输出看起来像上面那样?
ffllaacc 11..22..11,, CCooppyyrrighhtt ((CC)) 2000,2001,2002, 2003,220004,2 005,0200,0260,0210,0270 0 2J,o2s0h0 3C,o2a004,2005,2l0s0o6n, 007f l aJco scho mCeosa lwsiotnh AfBl OcL UcfTolEmaLecYs 1Nw.Oi2t .hW1 A,AR BRCSAoONpLTyUYrT.iE gL hYTt h Ni(OsC )W i AsR2 R0fA0rN0eT,eY2 .0s 0o 1fT,th2wi0as0r 2ei,,s2 0af0nr3de, e2y 0os0uo4 f,at 2rw0ea0 e,,2 0wa0en6ld,c 2oy0mo0eu7 ta or J eor hd iCswotearllicsbooumnte tiotf lruaencdd iecsrot mrceiesbr utwtaieit nhi tcA oBunSndOdiLetUriT oEcnLes 年。 t Na OiT nyW pacero Rn`AdfNilTtaYic.o' n sfT.oh ri sTd yeiptsea if`lrfsel .ea s 'f tfwor adreet,a iandl sy.ou 一种 e 欢迎在特定条件下重新分发。输入“flac”了解详情。
【问题讨论】:
【参考方案1】:而不是使用 system().. 你可以使用popen()。 然后,在父程序中读取每个子程序的输出,并用它做你想做的事情(例如,在输出每一行时同步一些互斥锁)。
【讨论】:
【参考方案2】:正如 pnm 指出的那样,popen() 可能是最好的方法。您仍然必须存储您通过管道读取的所有内容,最后将其写入您计划保存的任何位置,而不会将其与其他 popen() 调用的输出穿插。
一种更丑陋、效率更低但可能更简单的方法是设置您的 system() 作业以将其输出重定向到文件。然后,您可以有一个线程在 system() 调用完成后传递文件名,将文件内容全部附加到您的输出并删除临时文件。
或两者兼而有之。使用popen(),将管道读取的结果存储在内存中某处,当popen调用完成时将内存地址传递给输出线程,等等。
【讨论】:
【参考方案3】:除了 pnm 和 Duck 编写的内容之外,您还应该查看外部程序的手册页,并查看它们如何让您抑制不必要的输出。
最后,你可以通过 shell 抑制输出,例如
system("flac ... > /dev/null");
甚至是标准输出和标准错误:system("flac ... 2>&1");
【讨论】:
【参考方案4】:我认为 popen() 是最好的解决方案,但它可能需要一些工作。
我的快速解决方案可能是将每个应用程序的输出重定向到一个 tmp 文件。 然后在所有线程完成后将 tmp 文件复制到标准输出。
system("plop > tmp1");
【讨论】:
以上是关于在多线程应用程序中控制对输出的访问的主要内容,如果未能解决你的问题,请参考以下文章