用PB編寫多線程應用程序

 

  多線程是指一個程序內部同時執行的多個流程,與單線程相比,它至少有兩個方面的優點:第一,它可以更好地利用系統資源,比如CPU,若一個線程因I/O操作受阻,另一個線程仍可利用CPU來執行;第二,它更好地滿足了客戶的需求,因爲挑剔的客戶希望你開發的程序在顯示動畫的同時還能播放音樂、顯示文件、下載網絡文件等,這是單線程應用程序無法完成的。目前,支持多線程的開發工具主要有:Java、VC、Delphi和C++Builder。

  多線程強調的是一個進程內部有多個流程在同時執行,同時執行的概念相當於PB分佈式計算中的異步處理。也就是說,只要我們在一個程序內部實現了異步處理,就相當於實現了多線程。分析至此,下一步該怎麼做就不言而喻了:在一個應用程序內部實現分佈式計算,使用服務器推送技術,異步執行共享對象中的函數。

  下面就編寫一個Demo,介紹在PB中如何利用分佈式計算技術來開發多線程應用程序,其程序結構如圖1所示。uo—thread1和uo—thread2是類用戶對象uo—thread的兩個實例,uo—thread的功能是給實例變量li—Count自加5秒,自加的同時向中間對象uo—argv1和uo—argv2發送ue—thread消息。兩個中間對象的功能是把ue—thread消息轉化爲ue—thread1和ue—thread2後發給主窗口w—main。

  圖1 程序結構

  主窗口接收到ue—thread1消息後,顯示uo—thread1中自加變量的值,接收到ue—thread2後,顯示uo—thread2中自加變量的值。在單線程中,uo—thread1先執行,5秒鐘後uo—thread2開始執行,因此,前5秒內主窗口只能收到ue—thread1消息,後5秒內只能收到ue—thread2消息。在多線程中,uo—thread1和uo—thread2同時執行,因此w—main可以不斷地收到ue—thread1和ue—thread2消息。

  1.設計用戶對象uo—thread

  新建一個類用戶對象,命名爲uo—thread,添加如下兩個實例變量:

  NonVisualObject inv—arg

  Long li—Count //自加變量

  創建如下三個用戶函數:

  ⑴uf—start(),功能是:完成自加5秒並向中間對象發送ue—thread消息。腳本爲:

  Time t0

  t0= Now() //獲取當前時間

  Do While SecondsAfter(t0,Now())〈=5

  li—Count++//實例變量自加5秒

  inv—arg.TriggerEvent(′ue—thread′)

  //向中間對象發送ue—thread消息

  Loop

  ⑵uf—getcount(),功能是:獲取自加變量的瞬間值。其腳本爲:

  Return li—Count //返回實例變量

  ⑶uf—setparent(NonVisualObject nv—arg),調用時,使用中間對象爲參數。腳本爲:

  inv—arg=nv—arg

  //用中間對象給實例變量賦值

  2.設計中間對象uo—argv1和uo—argv2

  新建一個類用戶對象,命名爲uo—argv1,添加如下實例變量:

  Window win—arg

  創建用戶函數uf—setparent(Window w—argv),調用時,用主窗口作爲參數。其腳本爲:

  win—arg=w—argv

  //用主窗口對象給實例變量賦值

  聲明用戶事件ue—thread,用於對uo—thread1發出的uo—thread消息進行響應,其腳本爲:

  win—arg.TriggerEvent(″ue—thread1″)

  //向主窗口發送ue—thread1消息

  uo—argv2和uo—argv1完全一樣,只需將uo—argv1中的ue—thread1改爲uo—thread2即可。

  3.設計主窗口w—main

  主窗口外觀如圖2所示,凹下的三個控件分別爲:st—thread1、st—thread2、st—time,分別用於顯示uo—thread1和uo—thread2中自加變量的當前瞬間值和系統時間。聲明兩個用戶事件:ue—thread1和ue—thread2,分別用於對中間對象發送來的ue—thread1和ue—thread2消息進行響應。ue—thread1事件處理代碼爲:

  圖2 主窗口

  st—thread1.Text=String(uo—thread1.uf—getcount())

  ue—thread2事件的處理代碼爲:

  st—thread2.Text=String(uo—thread2.uf—getcount())

  w—main的Open事件代碼爲:

  uo—arg1 = Create uo—argv1

  //初始化中間對象的一個實例

  uo—arg2 = Create uo—argv2

  uo—arg1.uf—setParent(This) //給中間對象的實例變量賦值

  uo—arg2.uf—setParent(This)

  Timer(1) //啓動定時器

  Timer事件處理代碼爲:

  st—time.Text=String(Now())//顯示當前時間

  在“單線程”的Clicked事件中加入下列代碼:

  SharedObjectUnRegister(″object1″)

  //註銷先前註冊過的共享對象object1

  SharedObjectUnRegister(″object2″)

  //註銷先前註冊過的共享對象object2

  If IsValid(uo—thread1) Then Destroy uo—thread1  //若uo—thread1已經存在,先刪除

  If IsValid(uo—thread2) Then Destroy uo—thread2

  uo—thread1=Create uo—thread

  //初始化uo—thread1

  uo—thread2=Create uo—thread

  uo—thread1.uf—setparent(uo—argv1) //用中間對象給uo—thread1中的實例變量賦值

  uo—thread2.uf—setparent(uo—argv2)

  uo—thread1.Post uf—start() //執行uo—thread1中的uf—start()函數,完成後才執行下一句

  uo—thread2.Post uf—start()

  //上一條語句執行完成後纔會執行

  在“多線程”的Clicked事件中加入下列代碼:

  SharedObjectRegister(″uo—thread″,″object1″)

  //將uo—thread對象註冊爲object1

  SharedObjectRegister(″uo—thread″,″object2″)

  //將uo—thread對象註冊爲object2

  SharedObjectGet(″object1″,uo—thread1)

  //用uo—thread1引用共享對象object1

  SharedObjectGet(″object2″,uo—thread2)

  //用uo_thread2引用共享對象object2

  uo—thread1.uf—setparent(uo—argv1) //用中間對象給uo—thread1中的實例變量賦值

  uo—thread2.uf—setparent(uo—argv2)

  uo—thread1.Post uf—start() //利用服務器推送技術,異步調用共享對象中的uf—start()

  uo—thread2.Post uf—start()//相當於啓動線程

  4.執行

  執行程序後,圖2就是點擊“多線程”後執行的一瞬間
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章