關於執行緒的停止和掛起
在用執行緒的時候經常要啟動和掛起,原來d7的時候可以用resume和suspend(但是,建議不要用這2個方法,因為這2個方法在作業系統層面會造成死鎖),現在版本的TThread裡已經把這2個方法宣告為deprecated(我用的是xe2,具體不知道從哪個版本起)。原來在D7的時候要掛起執行緒,也沒用suspend,也是自己實現。
參考置頂帖(現在好象沒了,只有推薦了,見 http://bbs.csdn.net/topics/360046056 ),主要是參考它的退出執行緒方法,寫了個"通用"執行緒。
注:實際也不通用,我的情況是通用於主從方式的資料採集,某些系統資源,比如串列埠什麼的,資料採集執行緒和主執行緒共用,也就是一般情況下,資料採集執行緒通過串列埠迴圈不斷採集下位機的資料,當需要時,主執行緒可以掛起資料採集執行緒,讓出資源(串列埠)供主執行緒用。
資料採集執行緒中,資源(串列埠)佔用時候時間有長有短,長的時候可能數秒,主執行緒發出掛起命令後,採集執行緒不一定馬上結束工作,因而要判斷採集執行緒是否真正完成了"工作",主執行緒是否可以用資源(串列埠)了,這裡就有一個等待採集執行緒工作完成的問題。
程式碼用起來雖然沒發現有什麼問題,不過感覺有點彆扭,等待以後改進了
unit unHardWorkThread; interface uses Winapi.Windows, Winapi.Messages, System.Classes, System.SysUtils, System.SyncObjs, unGeneral; const WM_QUIT_HARD_THREAD = WM_USER + 301; DELAY_TIME_MIN = 10; type THardWorkThread = class(TThread) private FQuitEvent:TEvent; //退出執行緒 FSuspendEvent:TEvent; //掛起執行緒事件,有訊號表示正在工作,無訊號表示已經掛起 FWorkEvent:TEvent; //正在工作事件 FPIsInterrupt:PBoolean; //中斷 FDelayTime:Word; //延遲 FIsWorking:Boolean; //是否工作中 protected SupervisorCtl:TObject; //管理者物件 MsgHandle:THandle; //訊息目的視窗控制代碼 ErrorCount:Integer; //連續錯誤次數 procedure Execute; override; procedure DoWorkProc(const APIsInterrupt:PBoolean); virtual; abstract; //實際的工作過程(虛方法,子類必須實現) public constructor Create(ASupervisorCtl:TObject; AMsgHandle:THandle; ADelayTime:Word); destructor Destroy; override; function ExitThread(const AWaitTime:Integer):Boolean; //退出執行緒 function SuspendThread(const AWaitTime:Integer):Boolean; //掛起執行緒 function ResumeThread(const AWaitTime:Integer):Boolean; //恢復執行緒 function WaitForWorkCompleted(const AWaitTime:Integer):Boolean; //等待執行緒工作完成 end; implementation { THardWorkThread } constructor THardWorkThread.Create(ASupervisorCtl: TObject; AMsgHandle: THandle; ADelayTime:Word); begin inherited Create(True); SupervisorCtl:=ASupervisorCtl; MsgHandle:=AMsgHandle; FQuitEvent:=TEvent.Create; FSuspendEvent:=TEvent.Create; FWorkEvent:=TEvent.Create; New(FPIsInterrupt); FPIsInterrupt^:=False; FIsWorking:=False; ErrorCount:=0; FDelayTime:=ADelayTime; end; destructor THardWorkThread.Destroy; begin Dispose(FPIsInterrupt); FWorkEvent.Free; FSuspendEvent.Free; FQuitEvent.Free; inherited; end; { procedure THardWorkThread.DoWorkProc; begin end; } procedure THardWorkThread.Execute; var Msg:TMsg; begin FreeOnTerminate:=True; while True do begin if PeekMessage(Msg,0,0,0,PM_REMOVE) then begin if Msg.message = WM_QUIT_HARD_THREAD then begin FQuitEvent.SetEvent; Break; end; end; if FPIsInterrupt^ then begin Continue; end; FSuspendEvent.WaitFor(INFINITE); if FPIsInterrupt^ then begin Continue; end; FIsWorking:=True; FWorkEvent.ResetEvent; try DoWorkProc(FPIsInterrupt); finally FWorkEvent.SetEvent; FIsWorking:=False; end; if FDelayTime > DELAY_TIME_MIN then begin if DelayCanInterrupt(FDelayTime,FPIsInterrupt) then Continue; end; end; end; function THardWorkThread.ExitThread(const AWaitTime: Integer): Boolean; begin Result:=True; PostThreadMessage(ThreadID,WM_QUIT_HARD_THREAD,0,0); FPIsInterrupt^:=True; if FQuitEvent.WaitFor(AWaitTime) = wrTimeOut then Result:=False; end; function THardWorkThread.ResumeThread(const AWaitTime: Integer): Boolean; begin FSuspendEvent.SetEvent; Result:=True; end; function THardWorkThread.SuspendThread(const AWaitTime: Integer): Boolean; const Def_WaitTime = 10; begin Result:=False; if FSuspendEvent.WaitFor(Def_WaitTime) = wrSignaled then begin if WaitForWorkCompleted(AWaitTime) then begin FSuspendEvent.ResetEvent; Result:=True; end; end else begin FSuspendEvent.ResetEvent; Result:=True; end; end; function THardWorkThread.WaitForWorkCompleted(const AWaitTime: Integer): Boolean; begin if FIsWorking then Result:=FWorkEvent.WaitFor(AWaitTime) = wrSignaled else Result:=True; end; end.
這裡用了workevent,isworking,suspendevent,感覺有點亂,暫時還不清楚怎麼簡化。
相關推薦
關於執行緒的停止和掛起
在用執行緒的時候經常要啟動和掛起,原來d7的時候可以用resume和suspend(但是,建議不要用這2個方法,因為這2個方法在作業系統層面會造成死鎖),現在版本的TThread裡已經把這2個方法宣告為deprecated(我用的是xe2,具體不知道從哪個版本起)。原來在D
Linux 3.15核心將啟用非同步執行緒來減少掛起和恢復時間
Phoronix近期報道:Linux 3.15核心版本,預計將於2014年中期公佈,該版本“將有大量的ACPI和電源管理的更新”,並允許基於Linux的計算機掛起和恢復速度更快。 Linux的最新的穩定版本是3.13.6版本,Linux 3.14即將釋出,同時Linux 3.15的合併視窗即將開啟。
【.NET】執行緒的暫停和掛起
C#中使得多執行緒暫停掛起的方法有多種,但各有不同。我逐個說明: sleep方法是個靜態方法,由thread類來呼叫。它只能暫停當前執行緒,不能暫停其他執行緒。它接受的引數指名這個執行緒需要休眠多少時間。 suspend方法是普通方法,由物件呼叫,他不但能夠終止
執行緒和程序/阻塞和掛起
曾多次迷惑於阻塞和掛起狀態,後來才發現,有一些文章沒有區別,把(阻塞、掛起、等待)等同了,這時看語境作者說的是哪個。自己加以分析區別。 先大概這樣理解一下: 掛起:一般是主動的,由系統或程式發出,甚至於輔存中去。(不釋放CPU,可能釋放記憶體,放在外存) 阻塞:一般是被動的
java 執行緒間的通知和掛起處理 (wait/notify)
public class ThreadWaitNotifyTest{ private boolean flag = true; private void test(){ Object lock = new Object(); T
多執行緒之同步鎖 加鎖和執行緒停止
一.同步程式碼塊(同步鎖) 寫法: synchronized(鎖){ 上鎖的程式碼 } 當執行緒進入同步程式碼塊 會把鎖拿走 執行程式碼塊中的程式碼 程式碼執行完畢後 會把鎖還回去 如果執行緒遇到同步程式碼塊 發現沒有鎖 將進入等待(有鎖才可進) 鎖的注意:保證所有執行緒使用的是同一個鎖
【Java基礎_(執行緒篇_第一篇)】繼承Thread;實現runnable;sleep、wait用法和區別;Thread和Runnable區別;執行緒停止
一、執行緒兩種實現 1.繼承Thread類: (1)【直接在主類繼承】 package org; // 繼承 Thread 類 public class TestThreadofExt extends Thread { private static int count =
Java 多執行緒 join和interrupt 方法
簡述: 使用Java多執行緒中join和interrupt函式 《Java程式設計思想》 P669 ~ P670 一個執行緒可以再其他執行緒上呼叫join()方法,其效果是等待一段時間直到第二個執行緒結束才繼續執行。 如果某個執行緒在另一個執行緒t上呼叫t.join(), 此
Java執行緒-同步和非同步的區別
1. &nb
執行緒退出和執行緒資源回收問題
最近專案中遇到迴圈8M的記憶體洩漏問題,排查後發現是由於特殊場景下使子執行緒異常退出,主執行緒發現子執行緒退出便再次建立執行緒,此時未回收退出執行緒的資源造成了記憶體洩漏,導致資料庫宿主機oom,此問題不僅導致記憶體洩漏,還會使執行緒控制代碼用完導致其他程序無法分配執行緒的風險。 下面來
Java執行緒學習和總結(執行緒的概念)
執行緒的概念: 多執行緒允許在程式中併發執行多個指令流,每個指令流都稱為一個執行緒,彼此間互相獨立。它和程序一樣擁有獨立的執行控制,由作業系統負責排程,區別在於執行緒沒有獨立的儲存空間,而是和所屬程序中的其它執行緒共享一個儲存空間,這使得執行緒間的通訊遠較程序簡單。 具體到java記憶體模型,
JAVA多執行緒(三) 執行緒池和鎖的深度化
github演示程式碼地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/src/main/java/com/kawa/thread 1.執行緒池 1.1 執行緒池是什麼 Java中的執行緒
高併發程式設計:執行緒安全和ThreadLocal
執行緒安全的概念:當多個執行緒訪問某一個類(物件或方法)時,這個類始終都能表現出正確的行為,那麼這個類(物件或方法)就是執行緒安全的。 執行緒安全 說的可能比較抽象,下面就以一個簡單的例子來看看什麼是執行緒安全問題。 public class MyThread impleme
程序與執行緒理解和關係
程序 執行緒的含義 程序就是一個程式在一個數據集上的一次動態執行過程。 程序一般由程式、資料集、程序控制塊三部分組成。我們編寫的程式用來描述程序要完成哪些功能以及如何完成;資料集則是程式在執行過程中所需要使用的資源;程序控制塊用來記錄程序的外部特徵,描述程序的執行變化過程,系統可以利用它
Java併發程式設計:4種執行緒池和緩衝佇列BlockingQueue
一. 執行緒池簡介 1. 執行緒池的概念: 執行緒池就是首先建立一些執行緒,它們的集合稱為執行緒池。使用執行緒池可以很好地提高效能,執行緒池在系統啟動時即建立大量空閒的執行緒,程式將一個任務傳給執行緒池,執行緒池就會啟動一
執行緒停止(stop/intrrupt)
使一個執行緒停止有下列三種方式: 使用標記位(設定flag)停止執行緒; 呼叫stop方法強制停止執行緒; Thread類的interrupt方法; 一:使用falg停止執行緒 ////使用標記位 class Mythread3 implements
多執行緒--this和Thread.currentThread()詳解
在看多執行緒程式設計核心技術的時候,有一段程式碼讓我很困惑,所以在這裡記錄一下。 public class isalive { public static void main(String[] args) { // TODO Auto-generated method stub //T
js更新dom後頁面及時渲染問題(js執行緒阻塞和解決辦法)
參考:https://blog.csdn.net/qq_39542027/article/details/78893873 兩個概念:1,js是同步載入的 &nb
談談多執行緒Runnable和Callable介面
Runnable介面程式碼 public interface Runnable { public abstract void run(); } Callable介面程式碼 public interface Callable<V> { V c
執行緒停止的三種方式
執行緒停止的三種方式 設定標記位 使用stop()方法強制使執行緒退出 使用Thread.interrupt() 設定標記位,可以使執行緒正常退出 使用stop方法強制使執行