1. 程式人生 > >人為的無限迴圈即停止方法

人為的無限迴圈即停止方法

   有一些程式,比如系統監控工具,就應該是永遠執行。這種情況下,就會需要人為的無限迴圈:            

   loop

   data_gathering_procedure;

   end loop;

  由於持續的執行對cpu資源消耗嚴重,為了避免資源耗費殆盡,病保證資料收集過程儘可能有效的執行,

所以需要迴圈在執行中適當的暫停。

 loop

 data_gathering_procedure;

 dbms_lock.sleep(10) ;      //10秒內不作任何事情

end loop;

當然 ,那麼我們又如何結束這種無限的迴圈呢?通常我們都是以儲存過程形式執行,即便殺掉前臺程序也不會終止後臺程序。我們可以使用alter system kill session,但在某些版本的oracle中這個命令並不會殺掉一個卡在迴圈中的會話。

所以我們必須求助於作業系統的工具了,比如unix/linux平臺的kill以及windows的orakill.exe.這些工具需要知道oracle的系統程序的ID,在V$SSEION和V$PROCESS中很容易查出。

當然我們還有更好的方法解決這個問題,在迴圈中插入一個“命令直譯器”,然後通過資料庫內建的程序間通訊機制來發送命令即資料庫通道。

  declare

   pipename constant varchar2(12):='signaler';

   result integer;

   pipebuf   varchar2(64);

   begin

  /* 建立一個指定名字的私有管道*/

   result:=dbms_pipe.create_pipe(pipename);

   loop

   data_gathering_procedure;

   dbms_lock.sleep(10);

   /*檢查管道是否有資訊*/

   if dbms_pipe.receive_message(pipename ,0)=0

   then

   dbms_pipe.unpack_message(pipebuf);

   exit when pipebuf='stop';

   end if;

  end loop;

end; 

    現在可以構造一個簡單地夥伴程式,這個程式只需要通過在管道中傳送一個‘stop‘就可以終止這個迴圈的執行。

   declare

   pipename varchar2(12):='signaler';

   result integer :=dbms_pipe.create_pipe(pipename);

   begin

   dbms_pipe.pack_message('stop');

  end;