最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

2022年的 Tcl/Tk 編程入門參考 11.通道

2022-04-24 20:43 作者:象喻  | 我要投稿

事件循環(huán)

Tcl語言一般是一條語句執(zhí)行完畢后再執(zhí)行下一條,但是像通道操作的話,有可能需要很長時間。于是一些通道命令有在后臺運行的能力,不耽誤其它語句的執(zhí)行。但經(jīng)常有些代碼需要在通道操作完畢后再執(zhí)行,也就是說:一邊處理通道數(shù)據(jù),一邊執(zhí)行一些代碼,而后續(xù)代碼要等到通道處理完畢再執(zhí)行。面對這種情況就需要事件循環(huán)機制,通過vwait命令持續(xù)監(jiān)視,直到事件結(jié)束再繼續(xù)執(zhí)行后續(xù)代碼。

vwait

用法:vwait 標識變量名

vwait命令持續(xù)監(jiān)視標識變量(即便變量尚未創(chuàng)建)并阻止后續(xù)代碼的執(zhí)行,直到變量值發(fā)生變化(對于尚未創(chuàng)建的變量來說,只要設置個值就算更改)。如果給出一個永遠不會被修改的變量名,則會一直等待下去。

這個標識變量就相當于一個信號,后臺操作完畢之后,修改一下這個標識變量,就等于告訴vwait事件已經(jīng)結(jié)束了。否則就等于事件沒有結(jié)束,vwait就繼續(xù)持續(xù)監(jiān)視標識變量,阻止后續(xù)代碼執(zhí)行。

??監(jiān)視變量,阻止后續(xù)代碼運行
??變量值變更,vwait命令結(jié)束,退出事件循環(huán)
??雖然允許,但盡量避免嵌套調(diào)用vwait命令 (即嵌套事件循環(huán))

示例代碼請看 chan copy,嵌套事件循環(huán)和更多示例代碼請看官方文檔。


chan

chan命令是通道功能的大集合,也是一個比較尷尬的命令。在早期TCL語言里,跟通道相關(guān)的命令有十多個。從8.5版開始,其中大部分功能都集合到chan這一個命令里面了。但是,程序員們看了一下chan命令,功能一模一樣,還得多打四個字母,然后……就沒有然后了。

chan close <-> close

chan gets <-> gets

chan puts <-> puts

chan read <-> read

chan eof <-> eof

chan flush <-> flush

chan seek <-> seek

chan tell <-> tell

chan configure <-> fconfigure

chan copy <-> fcopy

chan event <-> fileevent

chan blocked <-> fblocked

"道理我都懂,不想多打4個字母……"


阻塞與非阻塞

對一個通道進行讀寫操作時,TCL語言默認會進入阻塞模式。也就是說,操作完成之前不會執(zhí)行其它動作。好處是,可以降低程序的復雜性,一步一步來。但也有很大的局限性,比如說圖形界面程序,在處于阻塞狀態(tài)時,菜單、按鈕都是不響應的。為了應對更多的情況,TCL語言還有非阻塞模式,同時可以做很多操作,比如網(wǎng)絡程序,同時可以跟很多機器收發(fā)消息。


seek & tell

chan seek的功能是設定當前的訪問位置(用文本文件舉例的話,就是設定當前光標的位置)。

chan tell的功能是返回當前通道的訪問位置。

chan seek 通道ID 偏移量 ?起始位置?

chan tell 通道ID

這兩個跟seek與tell命令是一樣的。

?


*提示:這兩個命令無法用于命令管道(位置始終返回-1)。


chan configure

設置通道或查看當前設置(同fconfigure命令)。

chan ?configure ?通道ID ??屬性名? ??屬性值? ??屬性2 ?值2?...

屬性:

-blocking 阻塞/非阻塞

-buffersize 緩沖區(qū)大小,默認4K

-encoding 字符編碼

-buffering 緩沖區(qū)模式:full(默認)緩沖區(qū)滿了再輸出;line按行自動輸出;none立即輸出

-eofchar 特殊文件結(jié)束符(除DOS系統(tǒng)是 \x1a 外,其它都是空字符)

-translation 換行符:auto(自動)、lf(換行)、cr(回車)、crlf(回車換行)、binary(二進制)

?



chan copy

復制通道內(nèi)容(同fcopy命令)。源通道與目標通道不同時(如字符編碼、二進制)TCL會自動轉(zhuǎn)換,但不保證轉(zhuǎn)換結(jié)果??梢灾付◤椭频淖址麛?shù)(不是字節(jié)數(shù))。

復制時處于阻塞狀態(tài),但如果使用-command參數(shù),則不會阻塞。此時chan copy會在后臺運行,Tcl語言會繼續(xù)執(zhí)行后面的語句。復制完畢后,會調(diào)用-command后面指定的命令,并將數(shù)據(jù)總長度作為參數(shù)自動傳遞給命令(所以命令至少需要接收一個參數(shù))。

如果預料到可能需要長時間才能完成的情況,則可以搭配vwait事件循環(huán)來使用。在調(diào)用命令中修改vwait監(jiān)視變量的值,通知vwait正常退出。

?



chan event

在通道可讀或可寫時執(zhí)行命令(即事件處理,同fileevent命令)

chan event 通道ID 讀取或?qū)懭胧录??事件處理命令?

這個功能監(jiān)視通道的狀態(tài),當通道處于可讀、或可寫的狀態(tài)時,就執(zhí)行我們設定好的命令。它用于非阻塞模式(因為在阻塞狀態(tài)時,TCL是不執(zhí)行其它指令的),主要實現(xiàn)“當數(shù)據(jù)準備好時再進行操作”的功能。不加可選參數(shù),單獨使用時,返回當前已經(jīng)設定的事件處理命令。加上可選參數(shù),就設定可讀、可寫狀態(tài)時的命令,需要注意的是,每個狀態(tài)只能設定一條命令,如果再次設置新的命令,就會替換舊的命令。如果設置的事件處理命令是空字符串,那么就會刪除之前的設定。



chan blocked

驗證通道是否處于阻塞狀態(tài)。如果通道被設置為非阻塞模式,則始終返回1。與 fblocked 命令功能相同

用法:chan blocked 通道ID


chan create

創(chuàng)建新的通道類型。

之前提到過四種通道:文件、網(wǎng)絡、命令管道和串行通信設備通道 這個功能可以創(chuàng)建新的通道類型。在這個命令里我們要設定新通道類型的訪問模式是讀取還是寫入,然后要按照規(guī)則把通道處理的代碼先創(chuàng)建好,再作為參數(shù)傳遞給create。關(guān)于創(chuàng)建的部分,需要參考refchan文檔,同時在這個文檔里面也提供了一個創(chuàng)建“字符串讀取通道”的例子,可以讓我們直接把字符串讀入到通道里——相當于創(chuàng)建了一個字符串類型的新通道。

新通道類型的創(chuàng)建參考官方文檔 Tcl Commands > refchan

??我是看文檔才弄明白這功能到底干嘛用的,有需要的請自行鉆研吧……


chan postevent

監(jiān)控create創(chuàng)建的通道是否能夠讀/寫。搭配 chan create 使用。

用法:chan postevent (chan create創(chuàng)建的通道ID) "參數(shù)列表(read/write)"

參考:wiki.tcl-lang.org/page/reflected+channel


chan names

默認返回全部通道名,也可以用字符串匹配(string match)的方式返回符合條件的通道名


chan pending

返回指定通道內(nèi)部緩沖的字節(jié)數(shù),用于防止惡意攻擊(比如網(wǎng)絡提交超大體積的數(shù)據(jù))。

用法:chan pending 模式(input|output) 通道ID

它分別統(tǒng)計輸入、輸出數(shù)據(jù)量,如果通道沒有開放某種模式(比如單寫入或單讀?。瑒t返回-1


chan pip

官方文檔說這個功能創(chuàng)建獨立管道,由一個讀取通道+一個寫入通道組成。就是一面進,一面出,類似于一個管道一樣。如果這個不好理解的話,也可以把這個功能想象成一個臨時文件,這個文件有只讀和只寫兩個通道。 先來看下具體例子:單獨運行這個命令,會返回兩個通道的ID,前面是讀取通道,后面是寫入通道。把兩個通道ID賦值給對應的變量,寫入內(nèi)容,再用flush命令輸出緩沖區(qū),然后就可在讀取通道讀取內(nèi)容了——就類似于一個臨時文件一樣。


這個功能,與tclx擴展庫中的pipe命令功能類似。不像官方文檔那么高端,tclx擴展庫文檔寫的通俗易懂,它常用于兩種情況:

一種是需要提前知道通道的ID,就是代碼寫到這兒,需要通道ID。但通道還沒建立呢,就先用pipe創(chuàng)建獨立管道,后續(xù)再把通道嫁接到這個獨立管道上。

第二種情況是有幾個不同屬性的通道(比如字符編碼不同),那么在轉(zhuǎn)移數(shù)據(jù)的時候,我們希望能夠手動處理一下,這個時候,也可以用這個功能。

當然,這是兩種常見情況,只要了解獨立管道的功能,在什么地方用都可以。


chan push

設定通道轉(zhuǎn)換程序,把通道里的數(shù)據(jù)通過轉(zhuǎn)換程序進行轉(zhuǎn)換。 麻煩的地方在于這個轉(zhuǎn)換程序必須得按照一定的規(guī)格來編寫,就是說有固定格式的。在文檔里專門有一章是介紹怎么創(chuàng)建轉(zhuǎn)換程序。在這里我簡單介紹一下,首先轉(zhuǎn)換程序必須要有 initialize 和 finalize 兩個子命令(“子命令”就是預設參數(shù),比如chan push,push就相當于chan的子命令) 其中initialize部分,要以列表形式返回轉(zhuǎn)換程序的全部子命令,這其中包括它自己和finalize。finalize在轉(zhuǎn)換程序的最后運行。此外,如果是寫入通道轉(zhuǎn)換的話,轉(zhuǎn)換程序必須包含write子命令;讀取通道轉(zhuǎn)換,必須包含read子命令。這兩個子命令在讀寫通道時生效。

?


這個例子里先創(chuàng)建了UP轉(zhuǎn)換命令,轉(zhuǎn)換過程是在read子命令里完成的。然后把UP命令設置為通道的轉(zhuǎn)換程序,在讀取通道內(nèi)容的時候,就可以看到,whoami命令的返回值,全都轉(zhuǎn)換成大寫了。


chan pop

取消通道轉(zhuǎn)換,與chan push搭配使用

用法:chan pop 通道ID



chan truncate

截斷文件通道內(nèi)容(僅用于文件通道,并且要有寫入權(quán)限)。在截斷前會刷新緩沖區(qū)(類似flush命令)。

用法:chan truncate 通道ID ?長度?

如果省略長度參數(shù),則以當前通道字節(jié)量為準

?




網(wǎng)絡通道

Tcl語言使用socket命令建立網(wǎng)絡通道,同樣用chan命令進行配置。但是程序員需要注意網(wǎng)絡通道的物理特性,比如傳輸速度、網(wǎng)絡延遲/掉線等問題,這些網(wǎng)絡特有的情況要有應對的代碼來進行處理。

socket有兩種模式,一種是建立網(wǎng)絡通道的客戶端模式,另一種是監(jiān)聽本機端口并做出應答的服務器端模式

客戶端模式:socket ?額外參數(shù)? 網(wǎng)絡主機名或IP地址 遠程端口

額外參數(shù): -myaddr 網(wǎng)絡接口:使用指定的網(wǎng)絡接口 -myport 端口:使用指定的端口(否則為系統(tǒng)分配端口) -async:異步模式

客戶端模式建立的網(wǎng)絡通道(TCP協(xié)議)默認使用當前系統(tǒng)的字符編碼。

額外參數(shù)解釋:-myaddr 指定網(wǎng)絡接口,比如同時有多個網(wǎng)卡,具體用哪個就通過這個參數(shù)指定。

-myport 使用指定的本地端口,默認是系統(tǒng)自動分配端口

-async 異步模式——默認情況下socket命令在建立網(wǎng)絡連接(即建立網(wǎng)絡通道)之后才會返回,如果連接的過程比較滿,程序就會卡住。異步模式就是socket命令立刻就會返回,程序可以繼續(xù)運行,然后我們要通過事件處理功能,去監(jiān)測網(wǎng)絡通道是否可用。


服務器端模式:socket -server 自定義命令 ?-myaddr 網(wǎng)絡接口? 本機端口

監(jiān)聽指定的本機端口,每當有客戶端連接時,調(diào)用自定義命令,并為每個客戶端創(chuàng)建網(wǎng)絡通道??蛇x參數(shù) -myaddr ?跟客戶端一樣,用于有多個網(wǎng)卡時。

調(diào)用自定義命令時會自動提交 [通道ID] [客戶端地址] [端口] 三個參數(shù),也就是說自定義命令至少需要接收三個參數(shù)(或者使用args)

?







2022年的 Tcl/Tk 編程入門參考 11.通道的評論 (共 條)

分享到微博請遵守國家法律
乌拉特前旗| 达尔| 昔阳县| 澜沧| 宁国市| 绥中县| 西昌市| 盖州市| 股票| 花莲县| 西丰县| 界首市| 黄浦区| 道真| 乌鲁木齐县| 安远县| 金平| 泾阳县| 肥城市| 博野县| 固安县| 汉沽区| 车致| 涿州市| 福海县| 南木林县| 凤阳县| 南乐县| 龙州县| 综艺| 镇远县| 红河县| 沈丘县| 海丰县| 崇礼县| 清镇市| 灵寿县| 长沙市| 井研县| 马龙县| 永宁县|