查看完整版本 : Windows pipe 問題

xianrenb 2017-11-27 07:59 PM

Windows pipe 問題

試過 google 過,不過想不到合適 keyword /找不到相關資料。
我想問的是,究竟 Windows 中,一個程式有無可能 hold 住個 pipe 而結束,令另一端不知道 pipe close 左又或者該程式結束?
實際 d 的問題是,如果按以下 UCI adapter 程式,個 engine program 有無可能唔知 STDIN eof ?
[url=http://repo.or.cz/uci2wb.git/blob/HEAD:/UCI2WB.c]http://repo.or.cz/uci2wb.git/blob/HEAD:/UCI2WB.c[/url]
呢個 adapter 有無問題?
又或者, engine 中應該點樣 detect ?

現在我的情況是,個象棋 AI engine ,有時在 WinBoard exit 後,個 engine process 還存在。

謝謝大家。

Susan﹏汪汪 2017-11-27 08:02 PM

只係估

正常program 關掉的話所有resources 都會release
包括pipe全部關掉

ncream 2017-11-27 08:17 PM

[quote]原帖由 [i]Susan﹏汪汪[/i] 於 2017-11-27 08:02 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471546992&ptid=27086536][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
只係估

正常program 關掉的話所有resources 都會release
包括pipe全部關掉 [/quote]

問題係唔正常關掉。又hold住pipe line。windows可否發現並release resource。

Susan﹏汪汪 2017-11-27 08:41 PM

[quote]原帖由 [i]ncream[/i] 於 2017-11-27 08:17 PM 發表 [url=http://www.discuss.com.hk/redirect.php?goto=findpost&pid=471547682&ptid=27086536][img]http://www.discuss.com.hk/images/common/back.gif[/img][/url]


問題係唔正常關掉。又hold住pipe line。windows可否發現並release resource。 [/quote]
正常或唔正常關都會release resources

例如memory leaks 或者invalid memory access咁
彈apps時系統係必須保證所有resources 都會released

先可以確保系統係回覆正常

汪汪都試過GPU寫memory 寫出界
通常GPU讀寫ram的方法同CPU的唔同
系統未必有能力阻止危險的操作、例如寫左落系統保護的記憶體

都會搞到成部電腦直接死機再重開

Susan﹏汪汪 2017-11-27 11:54 PM

[quote]原帖由 [i]xianrenb[/i] 於 2017-11-27 07:59 PM 發表 [url=http://www.discuss.com.hk/redirect.php?goto=findpost&pid=471546817&ptid=27086536][img]http://www.discuss.com.hk/images/common/back.gif[/img][/url]
試過 google 過,不過想不到合適 keyword ╱找不到相關資料。
我想問的是,究竟 Windows 中,一個程式有無可能 hold 住個 pipe 而結束,令另一端不知道 pipe close 左又或者該程式結束?
實際 d 的問題是,如果按以 ... [/quote]
可以試下Google broken pipe

有時候如果出error的話
會走stderr

xianrenb 2017-11-28 09:23 AM

還是 search 不到有用的資料。
以我找到的資料來理解,大概都是說程式就算沒有明確 close pipe , exit 了都會自動 close pipe 。
而象棋 engine 那邊, close 了 pipe 亦應該 detect 到 EOF 。
再不然就是會 error / exception 。
而現在卻是無 EOF / error / exception 。
唔通真的是 Windows 10 的 bug ?

Susan﹏汪汪 2017-11-28 09:57 AM

咁唔清楚了

汪汪冇Windows 機連試都冇得試

assembly.jc 2017-11-28 11:03 AM

[quote]原帖由 [i]xianrenb[/i] 於 2017-11-27 07:59 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471546817&ptid=27086536][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
試過 google 過,不過想不到合適 keyword /找不到相關資料。
我想問的是,究竟 Windows 中,一個程式有無可能 hold 住個 pipe 而結束,令另一端不知道 pipe close 左又或者該程式結束?
實際 d 的問題是,如果按以 ... [/quote]

睇你 link 入面的程式,StartEngine function 是 create an new child process。child processes 唔會自重關閉的。可看看 [url=https://msdn.microsoft.com/en-us/library/windows/desktop/ms686722(v=vs.85).aspx]https://msdn.microsoft.com/en-us/library/windows/desktop/ms686722(v=vs.85).aspx[/url]

[quote]
When the system is terminating a process, it does not terminate any child processes that the process has created. Terminating a process does not generate notifications for WH_CBT hook procedures.
[/quote]

ncream 2017-11-28 12:42 PM

[quote]原帖由 [i]xianrenb[/i] 於 2017-11-28 09:23 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471568066&ptid=27086536][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
還是 search 不到有用的資料。
以我找到的資料來理解,大概都是說程式就算沒有明確 close pipe , exit 了都會自動 close pipe 。
而象棋 engine 那邊, close 了 pipe 亦應該 detect 到 EOF 。
再不然就是會 err ... [/quote]

幾年前象棋奇兵已經令人類無法匹敵,一步16層,棄子局都睇穿。好似重係OPEN SOURCE。點解重要自己寫????

xianrenb 2017-11-28 01:12 PM

[quote]原帖由 [i]ncream[/i] 於 2017-11-28 12:42 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471576839&ptid=27086536][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]


幾年前象棋奇兵已經令人類無法匹敵,一步16層,棄子局都睇穿。好似重係OPEN SOURCE。點解重要自己寫???? [/quote]

講下相關資源:
[url=http://hgm.nubati.net/]http://hgm.nubati.net/[/url]
中的“WinBoard Xiangqi install” link 有 GUI + 3 個中國象棋 AI engine 。
其中一個是 ElephantEye :
[url=https://github.com/xqbase/eleeye]https://github.com/xqbase/eleeye[/url]

自己寫是看看自己能否寫得到類似程式。
如果是連將得勝的殘局,我的程式一般三十秒內最盡去到十幾、二十層左右吧?
最多些層數的話,原則上是計不到整套着法,但基本上通常只有第一着是正着時才能走足二十多着,變相已經計到正確着法。
實際 d 舉例,以下都是兩秒內計到。

+--\-/--+ 紅 黑
|+炮砲士+++|    
|#+將+炮+#| 帥 將
#+#+兵+卒+# 仕 士
+---傌-象-+ 相 象
+---俥-車-+ 傌 馬
#+#+砲+馬+# 俥 車
|#+卒+馬+#| 炮 砲
|+車傌帥+++| 兵 卒
+--/-\--+    

[[i] 本帖最後由 xianrenb 於 2017-11-28 03:41 PM 編輯 [/i]]

xianrenb 2017-11-28 01:21 PM

[quote]原帖由 [i]assembly.jc[/i] 於 2017-11-28 11:03 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471572398&ptid=27086536][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]


睇你 link 入面的程式,StartEngine function 是 create an new child process。child processes 唔會自重關閉的。可看看 [url=https://msdn.microsoft.com/en-us/library/windows/desktop/ms686722]https://msdn.microsoft.com/en-us/library/windows/desktop/ms686722[/url](v=vs.85).aspx

... [/quote]

但無論我個 engine 還是個 adapter ,應該遇到 EOF 都會 exit 。
所以不明白為何會這樣。
另一樣怪的是,我連 UCI2WB.exe 個 process 都找不到,只見 julia.exe (我個 engine 用 Julia 寫的)。

ncream 2017-11-28 01:53 PM

[quote]原帖由 [i]xianrenb[/i] 於 2017-11-28 01:12 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471578341&ptid=27086536][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]


講下相關資源:
[url=http://hgm.nubati.net/]http://hgm.nubati.net/[/url]
中的“WinBoard Xiangqi install” link 有 GUI + 3 個中國象棋 AI engine 。
其中一個是 ElephantEye :
[url=https://github.com/xqbase/eleeye]https://github.com/xqbase/eleeye[/url]

自己寫是看看自己能否 ... [/quote]

繼續努力,支持你。

最古老有將族老人(三段左右)

好多年前有人機對抗賽,什麼象棋世家,AI-MASTER.....。都是棋力5-6段。

當年象棋奇兵稱自己九段,在奕天已無敵手。

我以為人類已輸清,強如胡榮華,許銀川都唔掂,估唔到今日重發展緊。

assembly.jc 2017-11-28 01:57 PM

[quote]但無論我個 engine 還是個 adapter ,應該遇到 EOF 都會 exit 。
所以不明白為何會這樣。[/quote]


你的意思是有時會 exit,有時不會 exit?
不肯定 pipe line 左邊的 process 是否有 issue EOF ?


[quote]另一樣怪的是,我連 UCI2WB.exe 個 process 都找不到,只見 julia.exe (我個 engine 用 Julia 寫的)。 [/quote]
你在那裡找? windows 工作管理員?

[[i] 本帖最後由 assembly.jc 於 2017-11-28 01:59 PM 編輯 [/i]]

xianrenb 2017-11-28 03:52 PM

[quote]原帖由 [i]assembly.jc[/i] 於 2017-11-28 01:57 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471580688&ptid=27086536][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]



你的意思是有時會 exit,有時不會 exit?
不肯定 pipe line 左邊的 process 是否有 issue EOF ?



你在那裡找? windows 工作管理員? [/quote]

你的意思是,的確有可能有程式 hold 到個 pipe 而 exit ,所以無 EOF ?
通常開了 WinBoard load 我的程式做 first engine 後,棋局定勝負後 exit WinBoard 就無問題。
而有 load 我的程式做 second engine 而 exit WinBoard 就有問題。
在應該 WinBoard 、 adapter 及 engine run 緊的途中,是見不到 UCI2WB.exe 這個 process 的。
其實如果用其他 engine ,暫時都好似找不到相關 process 。
我在 Windows 的工作管理員處找 process 。
原來的問題是,有時會見到 julia.exe process 在 WinBoard exit 後還存在。

xianrenb 2017-11-28 10:39 PM

看來迷底已經解開,問題是 child process 按 [url=http://repo.or.cz/uci2wb.git/blob/HEAD:/UCI2WB.c]http://repo.or.cz/uci2wb.git/blob/HEAD:/UCI2WB.c[/url] 是同時取得了 4 個 handle ,本身無 close 到,所以即使 parent process (exit) close 左都無用,重有 child process 自己 hold 住。
[url=https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx]https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx[/url]
[quote]...The parent process uses the opposite ends of these two pipes to write to the child process's input and read from the child process's output. As specified in the STARTUPINFO structure, these handles are also inheritable. However, these handles must not be inherited. Therefore, before creating the child process, the parent process uses the SetHandleInformation function to ensure that the write handle for the child process's standard input and the read handle for the child process's standard input cannot be inherited....[/quote]
估計 call 番相關 setting 的 SetHandleInformation() 就無問題。

assembly.jc 2017-11-29 02:19 AM

[quote]原帖由 [i]xianrenb[/i] 於 2017-11-28 10:39 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471605222&ptid=27086536][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]
看來迷底已經解開,問題是 child process 按 [url=http://repo.or.cz/uci2wb.git/blob/HEAD:/UCI2WB.c]http://repo.or.cz/uci2wb.git/blob/HEAD:/UCI2WB.c[/url] 是同時取得了 4 個 handle ,本身無 close 到,所以即使 parent process (exit) close 左都無用,重有 child process ... [/quote]

想法雷同,應該是 UCI2WB.c  641 行,讓 child process 繼承了 hChildStdinRd,  hChildStdoutWr Handles,也因此 share 了它們到 child process 去。

而 parent process 已經不需用到, 故在 656, 657 已把 hChildStdinRd,  hChildStdoutWr 關閉。

但因 share 了 handles 需所有擁有它們的 processes 關閉它們,所指的 kernel objects 才會被released,pipe 也是 kernel object。

之前條 link 都有講 [url=https://msdn.microsoft.com/en-us/library/windows/desktop/ms686722(v=vs.85).aspx]https://msdn.microsoft.com/en-us/library/windows/desktop/ms686722(v=vs.85).aspx[/url]

[quote]
While open handles to kernel objects are closed automatically when a process terminates, [color=#ff0000]the objects themselves exist until all open handles to them are closed. Therefore, an object will remain valid after a process that is using it terminates if another process has an open handle to it[/color].
[/quote]

[[i] 本帖最後由 assembly.jc 於 2017-11-29 02:21 AM 編輯 [/i]]

xianrenb 2017-11-29 08:56 AM

[quote]原帖由 [i]assembly.jc[/i] 於 2017-11-29 02:19 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471612312&ptid=27086536][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]


想法雷同,應該是 UCI2WB.c  641 行,讓 child process 繼承了 hChildStdinRd,  hChildStdoutWr Handles,也因此 share 了它們到 child process 去。

而 parent process 已經不需用到, 故在 656, 657 已把 h ... [/quote]

Child process 只需要寫出至 STDOUT 及由 STDIN 處讀入,所以應該是 child process inherit 多了 hChildStdoutRd 及 hChildStdinWr 。
防止這兩個 handle 被 inherit 就得。

程式還有另外一些小問題,已改好。
約略試過,應該無問題了。

assembly.jc 2017-11-29 11:03 AM

[quote]原帖由 [i]xianrenb[/i] 於 2017-11-29 08:56 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471618626&ptid=27086536][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]


Child process 只需要寫出至 STDOUT 及由 STDIN 處讀入,所以應該是 child process inherit 多了 hChildStdoutRd 及 hChildStdinWr 。
防止這兩個 handle 被 inherit 就得。

程式還有另外一些小問題,已改好 ... [/quote]

I see. 原來與 pipe 是否 closed 無關,主要是 close hChildStdinWr,child process STDIN 就會收到 EOF。

xianrenb 2017-11-29 12:40 PM

[quote]原帖由 [i]assembly.jc[/i] 於 2017-11-29 11:03 AM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471624359&ptid=27086536][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]


I see. 原來與 pipe 是否 closed 無關,主要是 close hChildStdinWr,child process STDIN 就會收到 EOF。 [/quote]

不是無關,反而正正是問題所在呢!

Parent process 要 write 入 pipe , child process 要將 pipe 當 STDIN read 入 ,以另一個 pipe 當 STDOUT write 出,讓 parent process 從該 pipe read 入。
所以第一個 pipe , parent 要能 write , child 要能 read 。
第二個 pipe , parent 要能 read , child 要能 write 。
原來的 code , parent 那邊的 handle/pipe close 了兩個,設定算正確了,但同時錯誤地讓 child inherit 所有 4 個 handle 。
變成 child 有齊兩個 pipe 共 4 個的 read 及 write 端。
所以就算 parent exit / close 了餘下的 handle/pipe , child 自己仍然 keep 住 4 個 handle 。
因為未 close ,所以無論點樣 read ,都 read 不到 EOF 。
這樣就出問題了。
只讓 child process inherit 要用到的兩個 handle/pipe 做 STDIN 及 STDOUT ,問題就解決了。

Susan﹏汪汪 2017-11-29 01:14 PM

[quote]原帖由 [i]xianrenb[/i] 於 2017-11-29 12:40 PM 發表 [url=http://www.discuss.com.hk/redirect.php?goto=findpost&pid=471628742&ptid=27086536][img]http://www.discuss.com.hk/images/common/back.gif[/img][/url]


不是無關,反而正正是問題所在呢!

Parent process 要 write 入 pipe , child process 要將 pipe 當 STDIN read 入 ,以另一個 pipe 當 STDOUT write 出,讓 parent process 從該 pipe read 入。
所以第一個 ... [/quote]
咁有趣?
點解child會有晒所有端口

Bugs?

xianrenb 2017-11-29 01:23 PM

[quote]原帖由 [i]Susan﹏汪汪[/i] 於 2017-11-29 01:14 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471630118&ptid=27086536][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]

咁有趣?
點解child會有晒所有端口

Bugs? [/quote]

按個 UCI2WB adapter 的 code 來看,的確是 bug 。
依上面所述的方法修改後,就再無問題。

assembly.jc 2017-11-29 02:04 PM

[quote]原帖由 [i]xianrenb[/i] 於 2017-11-29 12:40 PM 發表 [url=http://computer.discuss.com.hk/redirect.php?goto=findpost&pid=471628742&ptid=27086536][img]http://computer.discuss.com.hk/images/common/back.gif[/img][/url]


不是無關,反而正正是問題所在呢!

Parent process 要 write 入 pipe , child process 要將 pipe 當 STDIN read 入 ,以另一個 pipe 當 STDOUT write 出,讓 parent process 從該 pipe read 入。
所以第一個 ... [/quote]
了解,child process 繼承了以下 4 個 handles 吧:
1. hChildStdinWr  
2.  hChildStdoutRd
3.  hChildStdinRd
4.  hChildStdoutWr

其中,hChildStdinRd 變成了 child process 的 STDIN, hChildStdoutWr 變成了 child process STDOUT 和 STDERR。[code] 633   siStartInfo.hStdInput = hChildStdinRd;
634   siStartInfo.hStdOutput = hChildStdoutWr;
635   siStartInfo.hStdError = hChildStdoutWr;[/code]估計 child process 沒有明確用 CloseHandle 關閉它們 (hChildStdinRd (STDIN), hChildStdoutWr (STDOUT)),因等待 EOF才結束,所以 associate 到 STDIN, STDOUT 和 STDERR 的 handles 需在 child process exit 才關閉。

即是說 child process 結束前 pipe objects 不會被清除,因 child process 的 hChildStdinRd (STDIN) 和 hChildStdoutWr (STDOUT) 仍然存在。

所以,在收到 EOF 前,child process 一直在使用 pipe objects。甚至 hChildStdinRd (STDIN) 也是透過 pipe object 才能接收到 EOF 的。因此事情發生的順序估計是:
1. child process STDIN (hChildStdinRd) 的 pipel line 來源 hChildStdinWr 被關閉 (在沒有繼承的情況下)
2. child process STDIN 收到 EOF
3. child process exit
4. all pipe objects 被清除

所以估計不繼承 hChildStdinWr 就可以。不過這只是推測,小弟未有寫 program 試過。

[[i] 本帖最後由 assembly.jc 於 2017-11-29 02:13 PM 編輯 [/i]]
頁: [1]
查看完整版本: Windows pipe 問題