1. 程式人生 > >關於執行緒的停止和掛起

關於執行緒的停止和掛起

在用執行緒的時候經常要啟動和掛起,原來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用法區別;ThreadRunnable區別;執行停止

一、執行緒兩種實現 1.繼承Thread類: (1)【直接在主類繼承】 package org; // 繼承 Thread 類 public class TestThreadofExt extends Thread { private static int count =

Java 多執行 joininterrupt 方法

簡述: 使用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

執行--thisThread.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

談談多執行RunnableCallable介面

Runnable介面程式碼 public interface Runnable { public abstract void run(); } Callable介面程式碼 public interface Callable<V> { V c

執行停止的三種方式

執行緒停止的三種方式 設定標記位 使用stop()方法強制使執行緒退出 使用Thread.interrupt() 設定標記位,可以使執行緒正常退出 使用stop方法強制使執行