用PB編寫多線程應用程序
2024-07-21 02:10:23
供稿:網友
多線程是指一個程序內部同時執行的多個流程,與單線程相比,它至少有兩個方面的優點:第一,它可以更好地利用系統資源,比如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就是點擊“多線程”后執行的一瞬間