暂停一个进程的运行

转两个关于"暂停一个进程的运行"的文章

1.     好像是在 www.codeproject.com 上看到的,原来是一个VC程序,我改了改,很简单。要暂停一个进程是没有直接的办法的,只能暂停进程中的所有线程,用了ToolHelp函数。而且这个程序只能在Win2000以上系统运行,因为用了OpenThread函数。  

//  pausep.cpp : Defines the entry point for the console application.
//

#include 
< windows.h >
#include 
< tlhelp32.h >
#include 
< iostream >

using   namespace  std;

BOOL PauseResumeThreadList(DWORD dwOwnerPID, 
bool  bResumeThread) 

HANDLE hThreadSnap 
=  NULL; 
BOOL bRet 
=  FALSE; 
THREADENTRY32 te32 
=  { 0 }; 

//  Take a snapshot of all threads currently in the system. 

hThreadSnap 
=  CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,  0 ); 
if  (hThreadSnap  ==  INVALID_HANDLE_VALUE) 
return  (FALSE); 

//  Fill in the size of the structure before using it. 

te32.dwSize 
=   sizeof (THREADENTRY32); 

//  Walk the thread snapshot to find all threads of the process. 
//  If the thread belongs to the process, add its information 
//  to the display list.

if  (Thread32First(hThreadSnap,  & te32)) 

do  

if  (te32.th32OwnerProcessID  ==  dwOwnerPID) 
{
HANDLE hThread 
=  OpenThread(THREAD_SUSPEND_RESUME, FALSE, te32.th32ThreadID);
if  (bResumeThread)
{
cout 
<<  _T( " Resuming Thread 0x " <<  cout.setf( ios_base::hex )  <<  te32.th32ThreadID  <<   ' ' ;
ResumeThread(hThread);
}
else
{
cout 
<<  _T( " Suspending Thread 0x " <<  cout.setf( ios_base::hex )  <<  te32.th32ThreadID  <<   ' ' ;
SuspendThread(hThread);
}
CloseHandle(hThread);

}
while  (Thread32Next(hThreadSnap,  & te32)); 
bRet 
=  TRUE; 

else  
bRet 
=  FALSE;  //  could not walk the list of threads 

//  Do not forget to clean up the snapshot object. 
CloseHandle (hThreadSnap); 

return  (bRet); 


BOOL ProcessList() 
{
HANDLE hProcessSnap 
=  NULL; 
BOOL bRet 
=  FALSE; 
PROCESSENTRY32 pe32 
=  { 0 }; 

//  Take a snapshot of all processes in the system. 
hProcessSnap  =  CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,  0 ); 

if  (hProcessSnap  ==  INVALID_HANDLE_VALUE) 
return  (FALSE); 

//  Fill in the size of the structure before using it. 
pe32.dwSize  =   sizeof (PROCESSENTRY32); 

//  Walk the snapshot of the processes, and for each process, 
//  display information. 

if  (Process32First(hProcessSnap,  & pe32)) 

do  

cout 
<<  _T( " PID " <<  pe32.th32ProcessID  <<   ' '   <<  pe32.szExeFile  <<   ' ' ;

while  (Process32Next(hProcessSnap,  & pe32)); 
bRet 
=  TRUE; 

else  
bRet 
=  FALSE;  //  could not walk the list of processes 

//  Do not forget to clean up the snapshot object. 

CloseHandle (hProcessSnap); 
return  (bRet); 




int  main( int  argc, TCHAR *  argv[], TCHAR *   /*  envp[]  */ )
{
if  (argc  <=   1 )
{
cerr 
<<  _T( " Usage: pausep PID /r " );
cerr 
<<  _T( " /r: resumes the execution of PID " );
ProcessList();
return   1 ;
}
else
{
DWORD pid 
=  _ttoi(argv[ 1 ]);
if  (pid  ==   0 )
{
cerr 
<<  _T( " Invalid PID number:  " <<  pid  <<   ' ' ;
return   1 ;
}
else
PauseResumeThreadList(pid, (argc 
>   2 &&  ( ! _tcsicmp(argv[ 2 ], _T( " /r " ))));
}

return   0 ;
}

============================ 我是华丽的分隔线 ====================================

2.大概代码从自己的进程管理器中分离出来了 自己研究研究  一个窗口  一个模块
9X下无法实现的关键是  OpenThread这个API函数不能用 无法获取线程句柄
所以也就无法挂起和恢复了  希望高手能搞定 呵呵
窗口代码

 

VERSION  5.00
Begin VB.Form Form7 
   BorderStyle     
=     1    ' Fixed Single
   Caption          =     " 线程查看 "
   ClientHeight    
=     3435
   ClientLeft      
=     45
   ClientTop       
=     435
   ClientWidth     
=     5340
   ClipControls    
=     0     ' False
   Icon             =     " Form7.frx " : 0000
   LinkTopic       
=     " Form7 "
   MaxButton       
=     0     ' False
   MinButton        =     0     ' False
   ScaleHeight      =     3435
   ScaleWidth      
=     5340
   ShowInTaskbar   
=     0     ' False
   StartUpPosition  =     1    ' 所有者中心
   Begin VB.Frame Frame2 
      Caption         
=     " 进程 "
      Height          
=     3375
      
Left              =     120
      TabIndex        
=     1
      Top             
=     0
      Width           
=     2415
      Begin VB.ListBox List1 
         BackColor       
=     & H8000000F &
         Height          
=     2940
         
Left              =     120
         TabIndex        
=     2
         Top             
=     240
         Width           
=     2175
      
End
   
End
   Begin VB.Frame Frame1 
      Caption         
=     " 线程ID "
      Height          
=     3375
      
Left              =     2760
      TabIndex        
=     0
      Top             
=     0
      Width           
=     2415
      Begin VB.ListBox List2 
         BackColor       
=     & H8000000F &
         Height          
=     2940
         
Left              =     120
         MultiSelect     
=     2    ' Extended
         TabIndex         =     3
         Top             
=     240
         Width           
=     2175
      
End
   
End
   Begin VB.Menu Threads 
      Caption         
=     " 线程菜单 "
      Visible         
=     0     ' False
      Begin VB.Menu ResumeT 
         Caption         
=     " 恢复(&R) "
      
End
      Begin VB.Menu Suspend 
         Caption         
=     " 挂起(&S) "
      
End
   
End
End
Attribute VB_Name 
=   " Form7 "
Attribute VB_GlobalNameSpace 
=   False
Attribute VB_Creatable 
=   False
Attribute VB_PredeclaredId 
=   True
Attribute VB_Exposed 
=   False

Private   Sub  Form_Load()
TList
End Sub

Private   Sub  List1_Click()  ' 线程列表
List2.Clear
For  i  =   0   To  Thread32_Enum(Thread(), ProcessId(List1.ListIndex).th32ProcessID)
    
If  Thread(i).th32OwnerProcessID  =  ProcessId(List1.ListIndex).th32ProcessID  Then
        List2.AddItem Thread(i).th32ThreadID
    
End   If
Next  i
End Sub

Private   Sub  List2_DblClick()
PopupMenu Threads
End Sub

Private   Sub  ResumeT_Click()
    
If  List2.Selected(i)  Then
        Thread_Resume List2.List(List2.ListIndex)
    
End   If
End Sub

Private   Sub  Suspend_Click()
    
If   MsgBox ( " 挂起线程可能导致该程序出错,确定要挂起?? " , vbDefaultButton2  +  vbOKCancel  +  vbQuestion,  " 挂起线程 " =  vbOK  Then
        
If  List2.Selected(i)  Then
            Thread_Suspend List2.List(List2.ListIndex)
        
End   If
    
End   If
End Sub


Function  Thread_Suspend(T_ID  As   Long As   Long   ' 挂起线程
Dim  hThread  As   Long
hThread 
=  OpenThread(THREAD_SUSPEND_RESUME,  False , T_ID)
Thread_Suspend 
=  SuspendThread(hThread)
End Function

Function  Thread_Resume(T_ID  As   Long As   Long   ' 恢复线程
Dim  hThread  As   Long
Dim  lSuspendCount  As   Long
hThread 
=  OpenThread(THREAD_SUSPEND_RESUME,  False , T_ID)
Thread_Resume 
=  ResumeThread(hThread)
End Function

Public   Sub  TList()
Dim  i  As   Integer
Dim  theloop  As   Long , snap  As   Long
Dim  Proc  As  PROCESSENTRY32
List1.Clear  
' 清空内容
List2.Clear
snap 
=  CreateToolhelp32Snapshot(TH32CS_SNAPall,  0 ' 获得进程"快照"的句柄
Proc.dwSize  =   Len (Proc)
theloop 
=  Process32First(snap, Proc)   ' 获取第一个进程,并得到其返回值
     While  theloop  <>   0   ' 当返回值非零时继续获取下一个进程
        List1.AddItem Proc.szExeFile
        
ReDim   Preserve  ProcessId(i)
        ProcessId(i).th32ProcessID 
=  Proc.th32ProcessID
        ProcessId(i).cntThreads 
=  Proc.cntThreads
        ProcessId(i).th32ParentProcessID 
=  Proc.th32ParentProcessID
        i 
=  i  +   1
        theloop 
=  Process32Next(snap, Proc)
    Wend
CloseHandle snap 
' 关闭进程"快照"句柄
End Sub

 

模块代码

 

Private   Declare   Function  Thread32First  Lib   " kernel32.dll "  ( ByVal  hSnapShot  As   Long ByRef  lpte  As  THREADENTRY32)  As   Boolean
Private   Declare   Function  Thread32Next  Lib   " kernel32.dll "  ( ByVal  hSnapShot  As   Long ByRef  lpte  As  THREADENTRY32)  As   Boolean

Public   Declare   Function  OpenThread  Lib   " kernel32.dll "  ( ByVal  dwDesiredAccess  As   Long ByVal  bInheritHandle  As   Boolean ByVal  dwThreadId  As   Long As   Long
Public   Declare   Function  ResumeThread  Lib   " kernel32.dll "  ( ByVal  hThread  As   Long As   Long
Public   Declare   Function  TerminateThread  Lib   " kernel32.dll "  ( ByVal  hThread  As   Long ByVal  dwExitCode  As   Long As   Boolean
Public   Declare   Function  SuspendThread  Lib   " kernel32.dll "  ( ByVal  hThread  As   Long As   Long

Public   Declare   Function  CreateToolhelp32Snapshot  Lib   " kernel32 "  ( ByVal  lFlags  As   Long ByVal  lProcessID  As   Long As   Long
Public   Declare   Function  Process32First  Lib   " kernel32 "  ( ByVal  hSnapShot  As   Long , uProcess  As  PROCESSENTRY32)  As   Long
Public   Declare   Function  Process32Next  Lib   " kernel32 "  ( ByVal  hSnapShot  As   Long , uProcess  As  PROCESSENTRY32)  As   Long

Public   Declare   Function  OpenProcess  Lib   " kernel32 "  ( ByVal  dwDesiredAccess  As   Long ByVal  bInheritHandle  As   Long ByVal  dwProcessId  As   Long As   Long
Public   Declare   Function  CloseHandle  Lib   " kernel32 "  ( ByVal  hObject  As   Long As   Long

Public  Type PROCESSENTRY32
    dwSize 
As   Long
    cntUsage 
As   Long
    th32ProcessID 
As   Long
    th32DefaultHeapID 
As   Long
    th32ModuleID 
As   Long
    cntThreads 
As   Long
    th32ParentProcessID 
As   Long
    pcPriClassBase 
As   Long
    dwFlags 
As   Long
    szExeFile 
As   String   *   260
End  Type
Public  Type THREADENTRY32
    dwSize 
As   Long
    cntUsage 
As   Long
    th32ThreadID 
As   Long
    th32OwnerProcessID 
As   Long
    tpBasePri 
As   Long
    tpDeltaPri 
As   Long
    dwFlags 
As   Long
End  Type

Public   Const  THREAD_SUSPEND_RESUME  As   Long   =   & H2

Public  ProcessId()  As  PROCESSENTRY32
Public  Thread()  As  THREADENTRY32

Public   Const  LB_SETHORIZONTALEXTENT  =   & H194
Public   Const  TH32CS_SNAPheaplist  =   & H1
Public   Const  TH32CS_SNAPPROCESS  =   & H2
Public   Const  TH32CS_SNAPthread  =   & H4
Public   Const  TH32CS_SNAPmodule  =   & H8
Public   Const  TH32CS_INHERIT  =   & H80000000
Public   Const  TH32CS_SNAPall  =  (TH32CS_SNAPheaplist  Or  TH32CS_SNAPPROCESS  Or  TH32CS_SNAPthread  Or  TH32CS_SNAPmodule)

Public   Function  Thread32_Enum( ByRef  Thread()  As  THREADENTRY32, lProcessID  As   Long As   Long
ReDim  Thread( 0 )
Dim  THREADENTRY32  As  THREADENTRY32
Dim  hSnapShot  As   Long
Dim  lThread  As   Long
hSnapShot 
=  CreateToolhelp32Snapshot(TH32CS_SNAPthread, lProcessID)
THREADENTRY32.dwSize 
=   Len (THREADENTRY32)
If  Thread32First(hSnapShot, THREADENTRY32)  =   False   Then
    Thread32_Enum 
=   - 1
    
Exit Function
Else
    
ReDim  Thread(lThread)
    Thread(lThread) 
=  THREADENTRY32
End   If

Do
    
If  Thread32Next(hSnapShot, THREADENTRY32)  =   False   Then
        
Exit   Do
    
Else
        lThread 
=  lThread  +   1
        
ReDim   Preserve  Thread(lThread)
        Thread(lThread) 
=  THREADENTRY32
    
End   If
Loop
Thread32_Enum 
=  lThread
End Function
<think>嗯,用户问的是如何暂停一个进程而不退出,然后让它继续运行。这个问题应该是关于Linux或者Unix系统的,因为Windows的命令行可能不太一样。首先,我得回忆一下常用的方法。 首先,我记得在Linux终端里,可以用Ctrl+Z来暂停当前正在前台运行进程。这样进程会被挂起,然后回到shell提示符。这时候进程的状态是停止的,但并没有结束,对吧?然后用户可能需要知道如何让这个进程继续运行,可能是在后台或者前台继续。 不过,暂停之后,如果想让进程在后台继续运行,应该用bg命令,这样进程就在后台运行了,不会占用当前的终端。而如果想让进程回到前台运行,用fg命令。但是用户的问题可能只是暂停和继续,不管前后台的问题,所以需要分步骤说明。 另外,可能还有其他方法,比如使用kill命令发送SIGSTOP信号来暂停进程,然后发送SIGCONT让它继续。这时候需要知道进程的PID。比如,先用ps或者top找到进程的PID,然后kill -SIGSTOP PID,暂停进程,再用kill -SIGCONT PID恢复。这个方法可能对后台进程更有效,特别是当用户没有在前台运行的时候。 那用户可能需要两种方法:一种是针对当前正在运行进程用Ctrl+Z,另一种是针对已知PID的进程用kill命令。我应该把这两种情况都介绍一下,这样用户可以根据具体情况选择合适的方法。 另外,可能需要解释一下jobs命令,用来查看被暂停的作业。这样用户暂停之后可以用jobs查看,然后用bg或fg加上作业号来管理。比如jobs -l显示详细信息,然后bg %1让作业1在后台继续,fg %1回到前台。这也是常用的流程。 需要注意的是,有些进程可能在暂停后继续运行会有问题,比如涉及硬件状态或者网络连接超时的情况,这时候恢复可能会出错。但一般情况下,大部分命令行程序都可以这样操作。 总结一下,步骤应该是: 1. 暂停进程: - 前台运行:Ctrl+Z - 已知PID:kill -SIGSTOP PID 2. 继续运行: - 恢复后台:bg [作业号] - 恢复前台:fg [作业号] - 使用SIGCONT:kill -SIGCONT PID 可能还需要提醒用户如何找到进程的PID,比如使用ps aux | grep 进程名,或者pgrep命令。另外,作业号是当用Ctrl+Z暂停时,系统分配的,可以通过jobs查看。 需要确保用户理解作业控制和信号的概念,避免误操作。比如,直接关闭终端可能会导致被暂停进程终止,所以如果想让进程持续运行,应该用nohup或者disown,但这个问题可能超出了当前问题的范围。 总之,回答应该分步骤,清晰说明两种方法,并给出常用命令的例子,让用户能够跟着操作。</think>在 Linux/Unix 系统中,你可以通过以下方法暂停进程运行而不退出,并后续恢复其运行: --- ### **方法一:前台进程的交互式操作** 1. **暂停进程(挂起)** 在终端中直接运行的前台进程,按下 `Ctrl + Z` 组合键,进程会立即被暂停,并显示类似 `[1]+ Stopped` 的信息。 2. **查看被暂停的作业** 输入 `jobs -l` 命令,可查看所有后台/暂停的作业及其编号(如 `[1]`)和进程 PID。 3. **恢复进程运行** - **恢复到前台继续运行**: ```bash fg %作业编号 # 例如 fg %1 ``` - **恢复到后台继续运行**: ```bash bg %作业编号 # 例如 bg %1 ``` --- ### **方法二:通过信号手动控制(需知道进程 PID)** 1. **暂停进程** 向进程发送 `SIGSTOP` 信号: ```bash kill -SIGSTOP <PID> # 替换 <PID> 为实际进程号 ``` 2. **恢复进程** 向进程发送 `SIGCONT` 信号: ```bash kill -SIGCONT <PID> # 替换 <PID> 为实际进程号 ``` --- ### **如何获取进程 PID?** - 通过名称查找 PID: ```bash pgrep <进程名> # 例如 pgrep vim ``` 或 ```bash ps aux | grep <进程名> ``` --- ### **注意事项** - 进程暂停后,仍会占用内存等资源,但不再消耗 CPU。 - 如果关闭终端,通过 `Ctrl + Z` 暂停进程可能会被终止(依赖终端会话管理)。若需持久化运行,建议结合 `nohup` 或 `tmux`/`screen` 工具。 如有其他疑问,欢迎进一步提问!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值