我寫過Zsh模塊。在那裏我有一個內置函數映射到Zsh命令。這個函數可以複製其標準輸入文件描述符:dup(fileno(stdin)),然後產生32個線程 - > I/O錯誤
/* Duplicate standard input */
oconf->stream = fdopen(dup(fileno(stdin)), "r");
然後,線程派生,其獲得oconf
結構。在該線程,我做的:
errno = 0;
/* Read e.g. 5 characters, putting them after previous portion */
int count = fread(buf + index, 1, read_size, oconf->stream);
/* Ensure that our whole data is a string - null terminated */
buf[ index + count ] = '\0';
if (errno) {
fprintf(oconf->err, "Read error (descriptor: %d): %s\n", fileno(oconf->stream), strerror(errno) >
}
如果我產卵32個線程的zsh:
for ((i=1; i<=32; i ++)); do
ls -R /Users/myuser/Documents | mybuiltin -A myhash_$i $i
done
然後2-3線程都從上面fprintf()
報道的I/O錯誤,如:
讀取錯誤(描述符:7):輸入/輸出錯誤
讀取錯誤(描述符:5)不適當的ioctl用於設備
讀取錯誤(描述:14):用於設備
不適當的ioctl
調試說,這些線程,經過多次(5-20)FREAD()重複,被堵在內核__read_nocancel()
。因此,文件描述符正在變得非常糟糕。
否則這個工程。管道正確傳遞來自ls -R
的數據,它被定製內建讀取。那麼危險在哪裏? dup()
如何在主線程中執行導致fread()
不可讀?我可能會懷疑我是否會在輔助線程中執行dup()
。但我只保留在安全的地方 - 主線程,然後將準備好的流FILE *
流傳遞到輔助線程。還試用POSIX open()
,read()
和close()
,結果是一樣的。