我有一個Python腳本,它使用multiprocessing.pool.map
來完成一些工作。因爲它打印到stdout
,所以打印到stderr
。我決定這將是很好,有一個單獨的日誌文件的每個流和一點思維制定了我應該像這樣運行它之後:從流重定向中糾正亂序打印
time ./ecisSearch.py 58Ni.conf 4 1 > >(tee stdout.log) 2> >(tee stderr.log >&2)
這給了我的日誌文件,並保留輸出在適當的流。然而,這是問題所在。如果我運行它沒有重定向我得到這個:
$ time ./ecisSearch.py 58Ni.conf 4 1
2015-01-09 14:42:37.524333: This job will perform 4 fit(s) //this is stdout
2015-01-09 14:42:37.524433: Threaded mapping of the fit function onto the starting point input set is commencing //this is stdout
2015-01-09 14:42:37.526641: Starting run #: 0 //this is stdout
2015-01-09 14:42:37.527018: Starting run #: 1 //this is stdout
2015-01-09 14:42:37.529124: Starting run #: 2 //this is stdout
2015-01-09 14:42:37.529831: Starting run #: 3 //this is stdout
2015-01-09 14:42:54.052522: Test of std err writing in run 0 is finished //this is stderr
2015-01-09 14:42:54.502284: Test of std err writing in run 1 is finished //this is stderr
2015-01-09 14:42:59.952433: Test of std err writing in run 3 is finished //this is stderr
2015-01-09 14:43:03.259783: Test of std err writing in run 2 is finished //this is stderr
2015-01-09 14:43:03.260360: Finished fits in job #: 1 preparing to output data to file //this is stdout
2015-01-09 14:43:03.275472: Job finished //this is stdout
real 0m26.001s
user 0m44.145s
sys 0m32.626s
但是,運行它的重定向生成以下輸出。
$ time ./ecisSearch.py 58Ni.conf 4 1 > >(tee stdout.log) 2> >(tee stderr.log >&2)
2015-01-09 14:55:13.188230: Test of std err writing in run 0 is finished //this is stderr
2015-01-09 14:55:13.855079: Test of std err writing in run 1 is finished //this is stderr
2015-01-09 14:55:19.526580: Test of std err writing in run 3 is finished //this is stderr
2015-01-09 14:55:23.628807: Test of std err writing in run 2 is finished //this is stderr
2015-01-09 14:54:56.534790: Starting run #: 0 //this is stdout
2015-01-09 14:54:56.535162: Starting run #: 1 //this is stdout
2015-01-09 14:54:56.538952: Starting run #: 3 //this is stdout
2015-01-09 14:54:56.563677: Starting run #: 2 //this is stdout
2015-01-09 14:54:56.531837: This job will perform 4 fit(s) //this is stdout
2015-01-09 14:54:56.531912: Threaded mapping of the fit function onto the starting point input set is commencing //this is stdout
2015-01-09 14:55:23.629427: Finished fits in job #: 1 preparing to output data to file //this is stdout
2015-01-09 14:55:23.629742: Job finished //this is stdout
real 0m27.376s
user 0m44.661s
sys 0m33.295s
只看時間戳,我們可以看到一些奇怪的事情發生在這裏。 stderr
和stdout
流不僅應該是不相互穿插的,而且stdout
組件似乎首先來自子流程,然後是來自「主」流程的內容,而不管其出現順序如何。 我知道stderr
是無緩衝的,並且stdout
被緩衝,但這並不能解釋爲什麼stdout
信息在它自己的流中失序。此外,從我的發帖不明顯,是所有的stdout
等到執行結束出現在屏幕上。
我的問題如下:這是爲什麼發生?,不太重要的有沒有辦法解決它?
緩衝。 'stderr'沒有緩衝,這就是爲什麼那些先顯示,然後我猜其他線保留在一個緩衝區,並在他們的進程結束時被刷新。可能的重複http://stackoverflow.com/questions/15931526/why-subprocess-stdout-to-a-file-is-written-out-of-order。不知道爲什麼這些重定向有所作爲,但是這是一個很好的地方。 – Lack 2015-01-09 20:12:50
請注意解釋標準輸出的亂序性質?如果只是stderr vs stdout緩衝也是我的選擇。但正如我在問題中所說的那樣,這不僅僅是這樣。標準輸出組件的順序也不正確。只有那些說「str err寫作測試」的部分被寫入stderr,其餘部分是stdout,並且時間戳記告訴我們的東西首先被寫入稍後出現的stdout。 – 2015-01-09 20:20:31
stdout上的無序行來自不同的子進程,對吧?每個都有自己的緩衝區。這似乎是一個非常好的解釋(不是Python特有的):http://www.pixelbeat.org/programming/stdio_buffering/ – Lack 2015-01-09 20:26:35