'\" '\" Copyright (c) 1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" '\" RCS: @(#) $Id: fileevent.n,v 1.2 2003/11/24 05:09:59 bbbush Exp $ '\" '\" The definitions below are for supplemental macros used in Tcl/Tk '\" manual entries. '\" '\" .AP type name in/out ?indent? '\" Start paragraph describing an argument to a library procedure. '\" type is type of argument (int, etc.), in/out is either "in", "out", '\" or "in/out" to describe whether procedure reads or modifies arg, '\" and indent is equivalent to second arg of .IP (shouldn't ever be '\" needed; use .AS below instead) '\" '\" .AS ?type? ?name? '\" Give maximum sizes of arguments for setting tab stops. Type and '\" name are examples of largest possible arguments that will be passed '\" to .AP later. If args are omitted, default tab stops are used. '\" '\" .BS '\" Start box enclosure. From here until next .BE, everything will be '\" enclosed in one large box. '\" '\" .BE '\" End of box enclosure. '\" '\" .CS '\" Begin code excerpt. '\" '\" .CE '\" End code excerpt. '\" '\" .VS ?version? ?br? '\" Begin vertical sidebar, for use in marking newly-changed parts '\" of man pages. The first argument is ignored and used for recording '\" the version when the .VS was added, so that the sidebars can be '\" found and removed when they reach a certain age. If another argument '\" is present, then a line break is forced before starting the sidebar. '\" '\" .VE '\" End of vertical sidebar. '\" '\" .DS '\" Begin an indented unfilled display. '\" '\" .DE '\" End of indented unfilled display. '\" '\" .SO '\" Start of list of standard options for a Tk widget. The '\" options follow on successive lines, in four columns separated '\" by tabs. '\" '\" .SE '\" End of list of standard options for a Tk widget. '\" '\" .OP cmdName dbName dbClass '\" Start of description of a specific option. cmdName gives the '\" option's name as specified in the class command, dbName gives '\" the option's name in the option database, and dbClass gives '\" the option's class in the option database. '\" '\" .UL arg1 arg2 '\" Print arg1 underlined, then print arg2 normally. '\" '\" RCS: @(#) $Id: fileevent.n,v 1.2 2003/11/24 05:09:59 bbbush Exp $ '\" '\" # Set up traps and other miscellaneous stuff for Tcl/Tk man pages. .if t .wh -1.3i ^B .nr ^l \n(.l .ad b '\" # Start an argument description .de AP .ie !"\\$4"" .TP \\$4 .el \{\ . ie !"\\$2"" .TP \\n()Cu . el .TP 15 .\} .ta \\n()Au \\n()Bu .ie !"\\$3"" \{\ \&\\$1 \\fI\\$2\\fP (\\$3) .\".b .\} .el \{\ .br .ie !"\\$2"" \{\ \&\\$1 \\fI\\$2\\fP .\} .el \{\ \&\\fI\\$1\\fP .\} .\} .. '\" # define tabbing values for .AP .de AS .nr )A 10n .if !"\\$1"" .nr )A \\w'\\$1'u+3n .nr )B \\n()Au+15n .\" .if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n .nr )C \\n()Bu+\\w'(in/out)'u+2n .. .AS Tcl_Interp Tcl_CreateInterp in/out '\" # BS - start boxed text '\" # ^y = starting y location '\" # ^b = 1 .de BS .br .mk ^y .nr ^b 1u .if n .nf .if n .ti 0 .if n \l'\\n(.lu\(ul' .if n .fi .. '\" # BE - end boxed text (draw box now) .de BE .nf .ti 0 .mk ^t .ie n \l'\\n(^lu\(ul' .el \{\ .\" Draw four-sided box normally, but don't draw top of .\" box if the box started on an earlier page. .ie !\\n(^b-1 \{\ \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' .\} .el \}\ \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul' .\} .\} .fi .br .nr ^b 0 .. '\" # VS - start vertical sidebar '\" # ^Y = starting y location '\" # ^v = 1 (for troff; for nroff this doesn't matter) .de VS .if !"\\$2"" .br .mk ^Y .ie n 'mc \s12\(br\s0 .el .nr ^v 1u .. '\" # VE - end of vertical sidebar .de VE .ie n 'mc .el \{\ .ev 2 .nf .ti 0 .mk ^t \h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n' .sp -1 .fi .ev .\} .nr ^v 0 .. '\" # Special macro to handle page bottom: finish off current '\" # box/sidebar if in box/sidebar mode, then invoked standard '\" # page bottom macro. .de ^B .ev 2 'ti 0 'nf .mk ^t .if \\n(^b \{\ .\" Draw three-sided box if this is the box's first page, .\" draw two sides but no top otherwise. .ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c .el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c .\} .if \\n(^v \{\ .nr ^x \\n(^tu+1v-\\n(^Yu \kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c .\} .bp 'fi .ev .if \\n(^b \{\ .mk ^y .nr ^b 2 .\} .if \\n(^v \{\ .mk ^Y .\} .. '\" # DS - begin display .de DS .RS .nf .sp .. '\" # DE - end display .de DE .fi .RE .sp .. '\" # SO - start of list of standard options .de SO .SH "STANDARD OPTIONS" .LP .nf .ta 5.5c 11c .ft B .. '\" # SE - end of list of standard options .de SE .fi .ft R .LP See the \\fBoptions\\fR manual entry for details on the standard options. .. '\" # OP - start of full description for a single option .de OP .LP .nf .ta 4c Command-Line Name: \\fB\\$1\\fR Database Name: \\fB\\$2\\fR Database Class: \\fB\\$3\\fR .fi .IP .. '\" # CS - begin code excerpt .de CS .RS .nf .ta .25i .5i .75i 1i .. '\" # CE - end code excerpt .de CE .fi .RE .. .de UL \\$1\l'|0\(ul'\\$2 .. .TH fileevent 3tcl 7.5 Tcl "Tcl Built-In Commands" .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME fileevent \- 在一個通道變得可讀或可寫的時候執行一個指令碼 .SH "總覽 SYNOPSIS" \fBfileevent \fIchannelId \fBreadable \fR?\fIscript\fR? .sp \fBfileevent \fIchannelId \fBwritable \fR?\fIscript\fR? .BE .SH "描述 DESCRIPTION" .PP 這個命令被用於建立\fI檔案事件處理器\fR。一個檔案事件處理器(handler)是在一個通道和一個指令碼之間的一個繫結,這樣在通道變得可讀或可寫的時候求這個指令碼的值。通常使用檔案事件處理器來允許在事件驅動的基礎上從另一個程序接收資料,這樣接受者可以在等待資料到來的時候繼續與使用者互動。如果一個應用在一個阻塞(模式下)的通道上呼叫 \fBgets\fR或 \fBread\fR,而此時沒有可獲得的資料,在輸入資料到來之前,程序將被阻塞,它將不能服務於其他事件,所以對於使用者它象是被“冷凍”了。使用 \fBfileevent\fR,程序可以在資料出現(present)的時候被告之,而只在不會導致阻塞的時候呼叫 \fBgets\fR或 \fBread\fR 。 .PP 給 \fBfileevent\fR的 \fIchannelId\fR 引數參照一個開啟的通道,比如從以前的 \fBopen\fR 或 \fBsocket\fR 命令的得到的返回值。如果指定了 \fIscript\fR 引數,則 \fBfileevent\fR 建立一個新的事件處理器: 在通道變得可讀或可寫(依賴於給 \fBfileevent\fR 的第二個引數)的時候求 \fIscript\fR 的值。在這種情況下 \fBfileevent\fR 返回一個空串。對於一個檔案 \fBreadable\fR 和 \fBwritable\fR事件處理器是獨立的,可以單獨的建立和刪除。但是,在一個特定的直譯器中在一個特定的時間上對於一個檔案最多隻能有一個\fBreadable\fR和一個 \fBwritable\fR 處理器。如果呼叫 \fBfileevent\fR而此時指定的處理器已經在呼叫的直譯器中存在,新的指令碼替換舊的那個。 .PP 如果沒有指定 \fIscript\fR 引數,\fBfileevent\fR 為 \fIchannelId\fR返回當前的指令碼,如果沒有則返回一個空串。如果 指定 \fIscript\fR 引數為一個空串則刪除這個事件處理器,如此將不會有指令碼被呼叫。在一個通道被關閉或它的直譯器被刪除的時候檔案的事件處理器也自動的被刪除。 .PP 如果在底層的裝置上有可獲得的未讀的資料則把一個通道考慮為可讀的。除了要從這個通道讀的最近的嘗試是不能在輸入緩衝中找到一個完整的行的一個 \fBgets\fR 呼叫的特殊情況之外,如果在一個輸入緩衝中有未讀的資料也把一個通道考慮未可讀的。這個特徵允許使用事件從一個在非阻塞模式下的檔案中一次讀一行。如果在底層的檔案或裝置上有檔案結束或出錯的條件出現也把一個通道考慮為可讀的。對於 \fIscript\fR 檢查這些條件和正確的處理它們是很重要的;例如,如果沒有對檔案結束的特定檢查,可能發生一個無限的迴圈,這裡\fIscript\fR 讀不到資料,返回,立即重新呼叫。 .PP 如果至少資料中有一位元組可以寫到底層檔案或裝置中而不阻塞,或者在底層的檔案或裝置上有錯誤的條件出現則把一個通道考慮為可寫的。 .PP 事件驅動 I/O 最好為使用 \fBfconfigure\fR 命令配置成非阻塞模式的通道工作。在阻塞模式下,如果你給它的資料比底層檔案或資料可接受的多,則 \fBputs\fR 命令將阻塞,而如果你讀的資料比已經準備好的多,則\fBgets\fR 或 \fBread\fR 命令將阻塞;在命令阻塞時不處理事件。在非阻塞模式下,\fBputs\fR、\fBread\fR和 \fBgets\fR從不阻塞。參見這些單獨命令的文件來得到關於它們如何處理阻塞和非阻塞通道的資訊。 .PP 給一個檔案事件的指令碼在呼叫\fBfileevent\fR 命令的直譯器的全域性的層次上執行(在任何 Tcl 過程的上下文之外)。如果在執行指令碼期間發生了錯誤則使用 \fBbgerror\fR 機制來報告錯誤。額外的,如果一個事件處理器曾經返回錯誤則刪除它;目的是防止缺陷很多的處理器導致無限迴圈。 .SH "感謝 CREDITS" .PP \fBfileevent\fR 基於由 Mark Diekhans 建立的 \fBaddinput\fR 命令。 .SH "參見 SEE ALSO" bgerror(n), fconfigure(n), gets(n), puts(n), read(n) .SH "關鍵字 KEYWORDS" asynchronous I/O, blocking, channel, event handler, nonblocking, readable, script, writable. .SH "[中文版維護人]" .B 寒蟬退士 .SH "[中文版最新更新]" .B 2001/08/13 .SH "《中國 Linux 論壇 man 手冊頁翻譯計劃》:" .BI http://cmpp.linuxforum.net .SH "跋" .br 本頁面中文版由中文 man 手冊頁計劃提供。 .br 中文 man 手冊頁計劃:\fBhttps://github.com/man-pages-zh/manpages-zh\fR