PB單線式自動排程程式設計(二)
繼上一篇PB單線式自動排程程式設計(一)
這篇來談談如何改進上一篇的STACK溢位問題吧。
其實這個方法並不難,但是要有足夠的觀念。
1.在原來的window上增加一個自訂事件ue_process
2.在window的共用變數(Instance variables)增加一個布林值
3.把原本在timer事件中的 程式碼全部移動到 ue_process事件中
4.在ue_process事件中的程式碼(不包含變數定義)開頭加入:
在程式碼最後加入:
5.在原本的timer事件中寫下下列程式碼:
原理是利用旗標變數ib_busy來阻擋事件被觸發,當ue_process被執行時 ib_busy被設定為true,假設此時工作A發生問題時,timer事件的再觸發執行時可以透過ib_busy避免ue_process被觸發,如此ue_process就不會有一直被stack起來的問題。
那為何程式要移至ue_process事件?這是因為程式若移至ue_process事件後該工作被執行時stack指標是處在ue_process上,當clock觸發timer事件時,由於timer事件並無被stack住,所以可以順利的執行,因此不會被擋住,該事件可以被順利處理不會stack起來。
當然此法是可以避免timer觸發事件無法消化的問題導致stack溢位而crash發生,但是卻也沒辦法保證其它工作可以正常執行,因為只要有其中一個工作不正常,整個程式依然處在停擺狀態。
比較好的方式就是利用多執行緒撰寫程式,可惜powerbuilder並非用來設計低階處理的程式工具,因此無法像C/C#班可以設計多執行緒;當然山不轉路轉,不能設計多執行緒,但可以設計多執行程式,所以另一種方法便是利用多程式執行方式達到此效果。
這篇來談談如何改進上一篇的STACK溢位問題吧。
其實這個方法並不難,但是要有足夠的觀念。
1.在原來的window上增加一個自訂事件ue_process
2.在window的共用變數(Instance variables)增加一個布林值
Boolean ib_busy = false
3.把原本在timer事件中的 程式碼全部移動到 ue_process事件中
4.在ue_process事件中的程式碼(不包含變數定義)開頭加入:
ib_busy = true
在程式碼最後加入:
ib_busy = false
5.在原本的timer事件中寫下下列程式碼:
If ib_busy = false Then
post event ue_process()
End If
原理是利用旗標變數ib_busy來阻擋事件被觸發,當ue_process被執行時 ib_busy被設定為true,假設此時工作A發生問題時,timer事件的再觸發執行時可以透過ib_busy避免ue_process被觸發,如此ue_process就不會有一直被stack起來的問題。
那為何程式要移至ue_process事件?這是因為程式若移至ue_process事件後該工作被執行時stack指標是處在ue_process上,當clock觸發timer事件時,由於timer事件並無被stack住,所以可以順利的執行,因此不會被擋住,該事件可以被順利處理不會stack起來。
當然此法是可以避免timer觸發事件無法消化的問題導致stack溢位而crash發生,但是卻也沒辦法保證其它工作可以正常執行,因為只要有其中一個工作不正常,整個程式依然處在停擺狀態。
比較好的方式就是利用多執行緒撰寫程式,可惜powerbuilder並非用來設計低階處理的程式工具,因此無法像C/C#班可以設計多執行緒;當然山不轉路轉,不能設計多執行緒,但可以設計多執行程式,所以另一種方法便是利用多程式執行方式達到此效果。
留言
而在多程行緒中, PB有一個指令是 shareobjectget ,
是不是用它就可以做到多執行緒了?
shareobjectregister
shareobjectunregister
shareobjectget
是PB裡面實現多執行緒的方式
(其實正確來說是:類多執行緒 a separate runtime session)
要注意的是shareobjectget的objectinstance有記項特性:
1.必須為不可視物件(unvisible)
2.無法使用全域環境(global variables unusable)
3.無法傳遞物件形態的參數(can't refer object type variables)