1. 程式人生 > >[遠航筆記流水賬]易大漠多線程初級教程086(1-3)

[遠航筆記流水賬]易大漠多線程初級教程086(1-3)

最好 線程數 變化 當我 編輯框 介紹 強制 循環 color

1.易大漠多線程初級之多線程介紹

什麽是多線程 沒什麽可說的

單線程

技術分享圖片

多線程

技術分享圖片


2.易大漠多線程初級之函數命令介紹

多線程的4個基礎函數:

技術分享圖片

註意:

1.如果掛起失敗 和恢復失敗 函數會返回-1 如果成功 那麽返回值肯定大於-1 用這個判斷是否掛起成功

2.要關閉線程 必須是要線程_強制關閉()和線程_關閉句柄()2個函數才可以 線程_強制關閉() 是負責關閉線程 而 線程_關閉句柄() 負責把線程id這個控制線程的入口給徹底註銷 我們以後再用這個線程id來控制線程都是無效的 雖然線程id內的值並沒有變化

3 線程id最好是程序集 方便 其他線程操作函數的調用

4 用線程_啟動腳本() 線程_掛起腳本() 線程_恢復腳本() 這是遠航老師封裝的 也是它推薦使用的 我們就不用精益模塊的線程函數 用這幾個來操作線程

5 暫時沒遇到線程啟動 線程強制關閉 線程關閉句柄失敗的情況 就不考慮這個情況了 註意這3個函數返回為假 表示操作失敗


小問題:如果沒有線程 那麽腳本執行期間我們無法操作界面 界面陷入假

技術分享圖片

如果循環沒有任何延遲 運行這循環 那麽界面就陷入假死 無法進行任何操作

建議:任何循環或多或少都要加入一點點延遲

避免這個情況的發聲

技術分享圖片


小問題:有的時候 線程掛起會失敗 例子裏面是因為線程裏面循環間隔沒有 運行太快 導致的

解決辦法:再循環內加入適當的延遲 同上面的問題


隨便看看:老師的3個線程函數和精益模塊的對應函數的區別

遠航老師這裏似乎是考慮到萬一啟動線程的線程id為空 會清理下資源? 不是很清楚幹什麽用

技術分享圖片遠航技術分享圖片精益模塊

結論:仔細看了一下 線程啟動的函數 精益模塊和遠航老師有區別 區別就是遠航的啟動會考慮到玩意返回的線程id為空 會自動把線程id對應的線程資源關閉掉 而精益模塊沒有這個方面的應對

至於掛起和恢復函數 遠航和精益模塊一樣 沒有區別



3.1易大漠多線程初級之許可證(線程鎖)應用

許可證(或者叫線程鎖)作用多個線程同時使用各種共有的資源 比如全局變量 界面的各個組件總不能你搶我搶 需要指定一個規則 比如說對同一個叫intX intY的全局變量 主要是負責記錄找圖後的返回坐標值 如果沒有規則可能出現同一時間 多個線程中的找題同時把找到的坐標寫入到這個全局變量中 那麽當我們要點擊intX intY 裏面的坐標 那麽這個坐標是屬於哪個線程裏面的找圖找到的坐標呢 會造成混亂 所以需要許可證(線程鎖)規定誰先誰後 ,比如線程1來了 它把許可證放在全局變量門前 表明這個全局變量 我線程1在用 其他線程來了看到這個線程1的許可證就明白了 就在門口等 線程1使用完了全局變量後 把門口的許可證拿走了 後面的線程看到了 就紛紛把自己的許可證放到門口 爭取使用權

個人感覺 許可證不能適用於大片代碼 因為許可證制度是一定時間內獨占 某個公共資源 其他線程都要等著 所以只在線程要使用某個公共資源的時候用一下


常見的公共資源:

1.全局變量

2.程序集變量

3界面的組件


因為老師許可證實例這部分沒有錄制完整


許可證的使用註意的幾點

1.許可證本身也是全局變量

2.每個線程對應一個屬於它的許可證

3 定義了線程的許可證 要操作公共資源 要用進入和離開

4 線程結束 請不要忘記刪除許可證

5 許可證不是萬能的 在操作界面的某些組件 許可證可能也會崩潰

3.2易大漠多線程初級之許可證(線程鎖)應用2

小知識:對於輔助延時()函數的理解

平時看多線程的源碼 純易語言的多線程源碼 他們的基本結構

技術分享圖片

使用了延時()和 處理事件()配合 讓循環不會導致界面陷入假死卡住狀態,遠航用的是 輔助延時() 看了下這個函數的源碼

裏面已經包含了 處理事件和延時

技術分享圖片


小知識:兩套許可證操作函數的選擇

易語言本身存在一套操作許可證的函數 參數統一要求的是整數型

.版本 2
.支持庫 EThread

創建進入許可證 ()
進入許可區 ()
退出許可區 ()
刪除進入許可證 ()

而遠航 或者說精益模塊裏面的另外一套操作許可證的函數 要求參數必須是許可證類型(推薦)

.版本 2

線程_創建許可證 ()
線程_刪除許可證 ()
線程_進入許可區 ()
線程_退出許可區 ()

偶得:自己練手做個簡單的多線程控制 8個進度條的代碼(做個紀念)

界面

技術分享圖片

.版本 2

.程序集 窗口程序集_啟動窗口
.程序集變量 許可證集合, 線程許可證, , "0"
.程序集變量 線程id, 整數型, , "0"
.程序集變量 進度條任務, 整數型, , "0"

.子程序 __啟動窗口_創建完畢

 1. 重置進度條的位置歸零
_啟動窗口.進度條1.位置 = 0
_啟動窗口.進度條2.位置 = 0
_啟動窗口.進度條3.位置 = 0
_啟動窗口.進度條4.位置 = 0
_啟動窗口.進度條5.位置 = 0
_啟動窗口.進度條6.位置 = 0
_啟動窗口.進度條7.位置 = 0
_啟動窗口.進度條8.位置 = 0

‘ 2.讓停止按鈕為灰色 開啟按鈕正常
_啟動窗口.按鈕_開啟.禁止 = 假
_啟動窗口.按鈕_關閉.禁止 = 真
 3. 清空編輯框的內容
_啟動窗口.編輯框_日誌.內容 = “”

.子程序 線程_測試函數, , 公開
.參數 當前線程標識id, 整數型
.局部變量 進度條任務標識, 整數型
.局部變量 i, 整數型

‘ 4 線程內 先從進度條任務數組 取到對應的進度條標識 然後開始完成進度條操作 該進度條操作完畢把日誌寫道編輯框裏面被查看


 3 完成上一個進度條操作 繼續找下一個進度條
.判斷循環首 (真)
    ‘ 1 從進度條任務數組獲取要執行的進度條標識 如果數組為空了則直接結束線程 結束前給日誌編輯框發送信息
     進入許可區 (許可證集合 [當前線程標識id])
    線程_進入許可區 (許可證集合 [當前線程標識id])
    .如果 (取數組成員數 (進度條任務) < 1)
         這裏要寫道日誌編輯框裏面
        跳出循環 ()

    .否則
         取出數組第一個元素
        進度條任務標識 = 進度條任務 [1]
        刪除成員 (進度條任務, 1, )
    .如果結束

    線程_退出許可區 (許可證集合 [當前線程標識id])
    ‘ 2 更具進度條標識來控制進度條進度不斷增加直到500結束
    .判斷開始 (進度條任務標識 = 1)
        i = _啟動窗口.進度條1.位置
        .判斷循環首 (i ≤ 500)
            i = i + 2
            _啟動窗口.進度條1.位置 = i
            輔助延時 (50)
        .判斷循環尾 ()

    .判斷 (進度條任務標識 = 2)
        i = _啟動窗口.進度條2.位置
        .判斷循環首 (i ≤ 500)
            i = i + 2
            _啟動窗口.進度條2.位置 = i
            輔助延時 (50)
        .判斷循環尾 ()

    .判斷 (進度條任務標識 = 3)
        i = _啟動窗口.進度條3.位置
        .判斷循環首 (i ≤ 500)
            i = i + 2
            _啟動窗口.進度條3.位置 = i
            輔助延時 (50)
        .判斷循環尾 ()

    .判斷 (進度條任務標識 = 4)
        i = _啟動窗口.進度條4.位置
        .判斷循環首 (i ≤ 500)
            i = i + 2
            _啟動窗口.進度條4.位置 = i
            輔助延時 (50)
        .判斷循環尾 ()

    .判斷 (進度條任務標識 = 5)
        i = _啟動窗口.進度條5.位置
        .判斷循環首 (i ≤ 500)
            i = i + 2
            _啟動窗口.進度條5.位置 = i
            輔助延時 (50)
        .判斷循環尾 ()

    .判斷 (進度條任務標識 = 6)
        i = _啟動窗口.進度條6.位置
        .判斷循環首 (i ≤ 500)
            i = i + 2
            _啟動窗口.進度條6.位置 = i
            輔助延時 (50)
        .判斷循環尾 ()

    .判斷 (進度條任務標識 = 7)
        i = _啟動窗口.進度條7.位置
        .判斷循環首 (i ≤ 500)
            i = i + 2
            _啟動窗口.進度條7.位置 = i
            輔助延時 (50)
        .判斷循環尾 ()

    .判斷 (進度條任務標識 = 8)
        i = _啟動窗口.進度條8.位置
        .判斷循環首 (i ≤ 500)
            i = i + 2
            _啟動窗口.進度條8.位置 = i
            輔助延時 (50)
        .判斷循環尾 ()

    .默認
         這裏要寫道日誌編輯框裏面
        跳出循環 ()
    .判斷結束

.判斷循環尾 ()

.子程序 _按鈕_開啟_被單擊
.局部變量 i, 整數型
.局部變量 局_線程id, 整數型
.局部變量 結果, 邏輯型

‘ 0 按鈕狀態調整一下
_啟動窗口.按鈕_開啟.禁止 = 真
_啟動窗口.按鈕_關閉.禁止 = 假

 1.根據界面上的線程數量 開始生成對應的許可證
清除數組 (許可證集合)
.計次循環首 (到整數 (_啟動窗口.編輯框_線程數.內容), )
    加入成員 (許可證集合, 線程_創建許可證 ())
    輔助延時 (200)
.計次循環尾 ()
‘ 2.生成一個進度條任務數組 每完成一個進度條 就把該進度條在數組對應的元素刪除掉
清除數組 (進度條任務)
.計次循環首 (8, i)
    加入成員 (進度條任務, i)

.計次循環尾 ()
 3 開始生成線程 並把線程對應的線程id寫入到線程id數組 等待備用
清除數組 (線程id)
.計次循環首 (到整數 (_啟動窗口.編輯框_線程數.內容), i)
    結果 = 線程_啟動腳本 (&線程_測試函數, i, 局_線程id)
    .如果真 (結果)
        加入成員 (線程id, 局_線程id)
    .如果真結束
    輔助延時 (2000)
.計次循環尾 ()


‘ 4 線程內 先從進度條任務數組 取到對應的進度條標識 然後開始完成進度條操作 該進度條操作完畢把日誌寫道編輯框裏面被查看

.子程序 _按鈕_關閉_被單擊
.局部變量 i, 整數型

 改變下按鈕狀態
_啟動窗口.按鈕_開啟.禁止 = 假
_啟動窗口.按鈕_關閉.禁止 = 真

 清理線程
.計次循環首 (取數組成員數 (線程id), i)
     線程id
    線程_強制結束 (線程id [i])
    線程_關閉句柄 (線程id [i])
    輔助延時 (200)
.計次循環尾 ()


 刪除許可證
.計次循環首 (取數組成員數 (許可證集合), i)

     加入成員 (許可證集合, 線程_創建許可證 ())
    線程_刪除許可證 (許可證集合 [i])
    輔助延時 (200)
.計次循環尾 ()


.子程序 __啟動窗口_將被銷毀
.局部變量 i, 整數型

 清理線程
.計次循環首 (取數組成員數 (線程id), i)

     線程id
    線程_強制結束 (線程id [i])
    線程_關閉句柄 (線程id [i])
    輔助延時 (200)
.計次循環尾 ()
 刪除許可證
.計次循環首 (取數組成員數 (許可證集合), i)

     加入成員 (許可證集合, 線程_創建許可證 ())
    線程_刪除許可證 (許可證集合 [i])
    輔助延時 (200)
.計次循環尾 ()


.子程序 _按鈕_重置_被單擊

.如果真 (_啟動窗口.按鈕_開啟.禁止 = 假)
    ‘ 1. 重置進度條的位置歸零
    _啟動窗口.進度條1.位置 = 0
    _啟動窗口.進度條2.位置 = 0
    _啟動窗口.進度條3.位置 = 0
    _啟動窗口.進度條4.位置 = 0
    _啟動窗口.進度條5.位置 = 0
    _啟動窗口.進度條6.位置 = 0
    _啟動窗口.進度條7.位置 = 0
    _啟動窗口.進度條8.位置 = 0

    ‘ 2.讓停止按鈕為灰色 開啟按鈕正常
    _啟動窗口.按鈕_開啟.禁止 = 假
    _啟動窗口.按鈕_關閉.禁止 = 真
    ‘ 3. 清空編輯框的內容
    _啟動窗口.編輯框_日誌.內容 = “”


.如果真結束



[遠航筆記流水賬]易大漠多線程初級教程086(1-3)