Windows进程管理

一、实验目的

(1)学会使用 VC 编写基本的 Win32 Consol Application(控制台应用程序)。

(2)通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟悉操作系统的进程概念,理解 Windows 进程的“一生”。

(3)通过阅读和分析实验程序,学习创建进程、观察进程、终止进程以及父子进程同步的基本程序设计方法。

二、总体设计

   2.1背景知识

Windows 所创建的每个进程都从调用 CreateProcess() API 函数开始,该函数的任务是在对象管理器子系统内初始化进程对象。每一进程都以调用 ExitProcess() 或 TerminateProcess() API 函数终止。通常应用程序的框架负责调用 ExitProcess() 函数。对于 C++ 运行库来说,这一调用发生在应用程序的 main() 函数返回之后。

 

     (1)创建进程
     CreateProcess() 调用的核心参数是可执行文件运行时的文件名及其命令行。表 1-1 详细地列出了每个参数的类型和名称。

表 1-1 CreateProcess() 函数的参数

参数名称

使用目的

LPCTSTR lpApplivationName

全部或部分地指明包括可执行代码的 EXE 文件的文件名

LPCTSTR lpCommandLine

向可执行文件发送的参数

LPSECURIITY_ATTRIBUTES
lpProcessAttributes

返回进程句柄的安全属性。主要指明这一句柄是否应该由其他
子进程所继承

LPSECURIITY_ATTRIBUTES
lpThreadAttributes

返回进程的主线程的句柄的安全属性

BOOL bInheritHandle

一种标志,告诉系统允许新进程继承创建者进程的句柄

DWORD dwCreationFlage

特殊的创建标志 (CREATE_SUSPENDED) 的位标记

LPVOID lpEnvironment

向新进程发送的一套环境变量;如为 null 值则发送调用者环境

LPCTSTR lpCurrentDirectory

新进程的启动目录

STARTUPINFO lpStartupInfo

STARTUPINFO 结构,包括新进程的输入和输出配置的详情

LPPROCESS_INFORMATION
lpProcessInformation

调用的结果块;发送新应用程序的进程和主线程的句柄和 ID

 

    可以指定第一个参数,即应用程序的名称,其中包括相对于当前进程的当前目录的全路径或者利用搜索方法找到的路径; lpCommandLine 参数允许调用者向新应用程序发送数据;接下来的三个参数与进程和它的主线程以及返回的指向该对象的句柄的安全性有关。

然后是标志参数,用以在 dwCreationFlags 参数中指明系统应该给予新进程什么行为。经常使用的标志是 CREATE_SUSPNDED,告诉主线程立刻暂停。当准备好时,应该使用 ResumeThread() API来启动进程。另一个常用的标志是 CREATE_NEW_CONSOLE,告诉新进程启动自己的控制台窗口,而不是利用父窗口。这一参数还允许设置进程的优先级,用以向系统指明,相对于系统中所有其他
的活动进程来说,给此进程多少 CPU 时间。
    接着是 CreateProcess() 函数调用所需要的三个通常使用缺省值的参数。第一个参数是lpEnvironment 参数,指明为新进程提供的环境;第二个参数是 lpCurrentDirectory,可用于向主创进程发送与缺省目录不同的新进程使用的特殊的当前目录;第三个参数是 STARTUPINFO 数据结构所必需的,用于在必要时指    

明新应用程序的主窗口的外观。
    CreateProcess() 的最后一个参数是用于新进程对象及其主线程的句柄和 ID 的返回值缓冲区。以 PROCESS_INFORMATION 结构中返回的句柄调用 CloseHandle() API 函数是重要的,因为如果不将这些句柄关闭的话,有可能危及主创进程终止之前的任何未释放的资源。

 

(2) 正在运行的进程
    如果一个进程拥有至少一个执行线程,则为正在系统中运行的进程。通常,这种进程使用主线程来指示它的存在。当主线程结束时,调用 ExitProcess() API 函数,通知系统终止它所拥有的所有正在运行、准备运行或正在挂起的其他线程。当进程正在运行时,可以查看它的许多特性,其中少数特性也允许加以修改。
    首先可查看的进程特性是系统进程标识符 (PID) ,可利用 GetCurrentProcessId() API 函数来查看,与 GetCurrentProcess() 相似,对该函数的调用不能失败,但返回的 PID 在整个系统中都可使用。其他的可显示当前进程信息的 API 函数还有 GetStartupInfo()和 GetProcessShutdownParameters() ,可给出进程存活期内的配置详情。

通常,一个进程需要它的运行期环境的信息。例如 API 函数 GetModuleFileName() 和GetCommandLine() ,可以给出用在 CreateProcess() 中的参数以启动应用程序。在创建应用程序时可使用的另一个 API 函数是 IsDebuggerPresent() 。
    可利用 API 函数 GetGuiResources() 来查看进程的 GUI 资源。此函数既可返回指定进程中的打开的 GUI 对象的数目,也可返回指定进程中打开的 USER 对象的数目。进程的其他性能信息可通过GetProcessIoCounters()、GetProcessPriorityBoost() 、GetProcessTimes() 和 GetProcessWorkingSetSize()
API 得到。以上这几个 API 函数都只需要具有 PROCESS_QUERY_INFORMATION 访问权限的指向所感兴趣进程的句柄。
    另一个可用于进程信息查询的 API 函数是 GetProcessVersion() 。此函数只需感兴趣进程的 PID(进程标识号) 。这一 API 函数与 GetVersionEx() 的共同作用,可确定运行进程的系统的版本号。


    (3) 终止进程
    所有进程都是以调用 ExitProcess() 或者 TerminateProcess() 函数结束的。但最好使用前者而不要使用后者,因为进程是在完成了它的所有的关闭“职责”之后以正常的终止方式来调用前者的。而外部进程通常调用后者即突然终止进程的进行,由于关闭时的途径不太正常,有可能引起错误的行为。
    TerminateProcess() API 函数只要打开带有 PROCESS_TERMINATE 访问权的进程对象,就可以终止进程,并向系统返回指定的代码。这是一种“野蛮”的终止进程的方式,但是有时却是需要的。如果开发人员确实有机会来设计“谋杀” (终止别的进程的进程) 和“受害”进程 (被终止的进程) 时,应该创建一个进程间通讯的内核对象——如一个互斥程序——这样一来,“受害”进程只在等待或周期性地测试它是否应该终止。


    (4)进程同步
    Windows 提供的常用对象可分成三类:核心应用服务、线程同步和线程间通讯。其中,开发人员可以使用线程同步对象来协调线程和进程的工作,以使其共享信息并执行任务。此类对象包括互锁数据、临界段、事件、互斥体和信号等。
    多线程编程中关键的一步是保护所有的共享资源,工具主要有互锁函数、临界段和互斥体等;另一个实质性部分是协调线程使其完成应用程序的任务,为此,可利用内核中的事件对象和信号。
    在进程内或进程间实现线程同步的最方便的方法是使用事件对象,这一组内核对象允许一个线程对其受信状态进行直接控制 (见表 1-2) 。
    而互斥体则是另一个可命名且安全的内核对象,其主要目的是引导对共享资源的访问。拥有单一访问资源的线程创建互斥体,所有想要访问该资源的线程应该在实际执行操作之前获得互斥体,而在访问结束时立即释放互斥体,以允许下一个等待线程获得互斥体,然后接着进行下去。
    与事件对象类似,互斥体容易创建、打开、使用并清除。利用 CreateMutex() API 可创建互斥体,创建时还可以指定一个初始的拥有权标志,通过使用这个标志,只有当线程完成了资源的所有的初始化工作时,才允许创建线程释放互斥体。

表 1-2 用于管理事件对象的 API

API 名称

描述

CreateEvent()

在内核中创建一个新的事件对象。此函数允许有安全性设置、手工还是
自动重置的标志以及初始时已接受还是未接受信号状态的标志

OpenEvent()

创建对已经存在的事件对象的引用。此 API 函数需要名称、继承标志和
所需的访问级别

SetEvent()

将手工重置事件转化为已接受信号状态

ResetEvent()

将手工重置事件转化为非接受信号状态

PulseEvent()

将自动重置事件对象转化为已接受信号状态。当系统释放所有的等待它
的线程时此种转化立即发生

 

为了获得互斥体,首先,想要访问调用的线程可使用 OpenMutex() API 来获得指向对象的句柄;然后,线程将这个句柄提供给一个等待函数。当内核将互斥体对象发送给等待线程时,就表明该线程获得了互斥体的拥有权。当线程获得拥有权时,线程控制了对共享资源的访问——必须设法尽快地放弃互斥体。放弃共享资源时需要在该对象上调用 ReleaseMute() API。然后系统负责将互斥体拥有权传递给下一个等待着的线程 (由到达时间决定顺序) 。

 

2.2 设计步骤

    (1)编写基本的 Win32 Consol Application
    步骤 1:登录进入 Windows 系统,启动 VC++ 6.0。
    步骤 2:在“FILE”菜单中单击“NEW”子菜单,在“projects”选项卡中选择“Win32 ConsolApplication”,然后在“Project name”处输入工程名,在“Location” 处输入工程目录。创建一个新的控制台应用程序工程。
    步骤 3:在“FILE”菜单中单击“NEW”子菜单,在“Files”选项卡中选择“C++ Source File”,然后在“File” 处输入 C/C++源程序的文件名。
    步骤 4:将清单 1-1 所示的程序清单复制到新创建的 C/C++源程序中。编译成可执行文件。
    步骤 5:在“开始”菜单中单击“程序”-“附件”-“命令提示符”命令,进入 Windows“命令提示符”窗口,然后进入工程目录中的 debug 子目录,执行编译好的可执行程序,列出运行结果(如果运行不成功,则可能的原因是什么?)
    (2) 创建进程
     本实验显示了创建子进程的基本框架。该程序只是再一次地启动自身,显示它的系统进程 ID和它在进程列表中的位置。
    步骤 1:创建一个“Win32 Consol Application”工程,然后拷贝清单 1-2 中的程序,编译成可执行文件。
    步骤 2:在“命令提示符”窗口运行步骤 1 中生成的可执行文件,列出运行结果。按下ctrl+alt+del,调用 windows 的任务管理器,记录进程相关的行为属性。
    步骤 3:在“命令提示符”窗口加入参数重新运行生成的可执行文件,列出运行结果。按下ctrl+alt+del,调用 windows 的任务管理器,记录进程相关的行为属性。
    步骤 4:修改清单 1-2 中的程序,将nClone的定义和初始化方法按程序注释中的修改方法进行修改,编译成可执行文件(执行前请先保存已经完成的工作)。再按步骤 2 中的方式运行,看看结果会有什么不一样。列出行结果。从中你可以得出什么结论?说明nClone的作用。 变量的定义和初始化方法(位置)对程序的执行结果有影响吗?为什么?
   (3) 父子进程的简单通信及终止进程
    步骤 1:创建一个“Win32 Consol Application”工程,然后拷贝清单 1-3 中的程序,编译成可执行文件。
    步骤 2:在 VC 的工具栏单击“Execute Program” (执行程序) 按钮,或者按 Ctrl + F5 键,或者在“命令提示符”窗口运行步骤 1 中生成的可执行文件,列出运行结果。
    步骤 3:按源程序中注释中的提示,修改源程序 1-3,编译执行(执行前请先保存已经完成的工作),列出运行结果。在程序中加入跟踪语句,或调试运行程序,同时参考 MSDN 中的帮助文件CreateProcess()的使用方法,理解父子进程如何传递参数。给出程序执行过程的大概描述。
    步骤 4:按源程序中注释中的提示,修改源程序 1-3,编译执行,列出运行结果。
    步骤 5:参 考 MSDN 中 的 帮 助 文 件 CreateMutex() 、 OpenMutex() 、 ReleaseMutex() 和WaitForSingleObject()的使用方法,理解父子进程如何利用互斥体进行同步的。给出父子进程同步过程的一个大概描述。

三、详细设计

清单 1-1

// hello 项目
# include <iostream>
void main()
{
std::cout << "Hello, Win32 Consol Application" << std :: endl ;
}

清单 1-2

#include <windows.h>
#include <iostream>
#include <stdio.h>
// 创建传递过来的进程的克隆过程并赋于其 ID 值
void StartClone(int nCloneID)
{
// 提取用于当前可执行文件的文件名
TCHAR szFilename[MAX_PATH] ;
GetModuleFileName(NULL, szFilename, MAX_PATH) ;
// 格式化用于子进程的命令行并通知其 EXE 文件名和克隆 ID
TCHAR szCmdLine[MAX_PATH];
sprintf(szCmdLine,"\"%s\" %d",szFilename,nCloneID);
// 用于子进程的 STARTUPINFO 结构
STARTUPINFO si;
ZeroMemory(&si , sizeof(si) ) ;
si.cb = sizeof(si) ; // 必须是本结构的大小
// 返回的用于子进程的进程信息
PROCESS_INFORMATION pi;
// 利用同样的可执行文件和命令行创建进程,并赋于其子进程的性质
BOOL bCreateOK=::CreateProcess(
szFilename, // 产生这个 EXE 的应用程序的名称
szCmdLine, // 告诉其行为像一个子进程的标志
NULL, // 缺省的进程安全性
NULL, // 缺省的线程安全性
FALSE, // 不继承句柄
CREATE_NEW_CONSOLE, // 使用新的控制台
NULL, // 新的环境
NULL, // 当前目录
&si, // 启动信息
&pi) ; // 返回的进程信息
// 对子进程释放引用
if (bCreateOK)
{
CloseHandle(pi.hProcess) ;
CloseHandle(pi.hThread) ;
}
}
int main(int argc, char* argv[] )
{
// 确定派生出几个进程,及派生进程在进程列表中的位置
int nClone=0;
//修改语句: int nClone;
//第一次修改: nClone=0;
nClone=0;
if (argc > 1)
{
// 从第二个参数中提取克隆 ID
:: sscanf(argv[1] , "%d" , &nClone) ;
}
//第二次修改: nClone=0;
// 显示进程位置
std :: cout << "Process ID:" << :: GetCurrentProcessId()
<< ", Clone ID:" << nClone
<< std :: endl;
// 检查是否有创建子进程的需要
const int c_nCloneMax=5;
if (nClone < c_nCloneMax)
{
// 发送新进程的命令行和克隆号
StartClone(++nClone) ;
}
// 等待响应键盘输入结束进程
getchar();
return 0;
}

清单 1-3

// procterm 项目
# include <windows.h>
# include <iostream>
# include <stdio.h>
static LPCTSTR g_szMutexName = "w2kdg.ProcTerm.mutex.Suicide" ;
// 创建当前进程的克隆进程的简单方法
void StartClone()
{
// 提取当前可执行文件的文件名
TCHAR szFilename[MAX_PATH] ;
GetModuleFileName(NULL, szFilename, MAX_PATH) ;
// 格式化用于子进程的命令行,字符串“ child”将作为形参传递给子进程的 main 函数
TCHAR szCmdLine[MAX_PATH] ;
//实验 1-3 步骤 3:将下句中的字符串 child 改为别的字符串,重新编译执行,执行前请先保存已经完成的工作
sprintf(szCmdLine, "\"%s\"child" , szFilename) ;
// 子进程的启动信息结构
STARTUPINFO si;
ZeroMemory(&si,sizeof(si)) ;
si.cb = sizeof(si) ; // 应当是此结构的大小
// 返回的用于子进程的进程信息
PROCESS_INFORMATION pi;
// 用同样的可执行文件名和命令行创建进程,并指明它是一个子进程
BOOL bCreateOK=CreateProcess(
szFilename, // 产生的应用程序的名称 (本 EXE 文件)
szCmdLine, // 告诉我们这是一个子进程的标志
NULL, // 用于进程的缺省的安全性
NULL, // 用于线程的缺省安全性
FALSE, // 不继承句柄
CREATE_NEW_CONSOLE, //创建新窗口
NULL, // 新环境
NULL, // 当前目录
&si, // 启动信息结构
&pi ) ; // 返回的进程信息
// 释放指向子进程的引用
if (bCreateOK)
{
CloseHandle(pi.hProcess) ;
CloseHandle(pi.hThread) ;
}
}
void Parent()
{//当等待仍在挂起状态时,句柄被关闭,那么函数行为是未定义的。该句柄必须具有 SYNCHRONIZE 访问权限。
// 创建“自杀”互斥程序体
HANDLE hMutexSuicide=CreateMutex(
NULL, // 缺省的安全性
TRUE, // 最初拥有的
g_szMutexName) ; // 互斥体名称
if (hMutexSuicide != NULL)
{
// 创建子进程
std :: cout << "Creating the child process." << std :: endl;
StartClone() ;
// 指令子进程“杀”掉自身
std :: cout << "Telling the child process to quit. "<< std :: endl;
//等待父进程的键盘响应
getchar() ;
//释放互斥体的所有权,这个信号会发送给子进程的 WaitForSingleObject 过程
ReleaseMutex(hMutexSuicide) ;
// 消除句柄
CloseHandle(hMutexSuicide) ;
}
}
void Child()
{
// 打开“自杀”互斥体
HANDLE hMutexSuicide = OpenMutex(
SYNCHRONIZE, // 打开用于同步
FALSE, // 不需要向下传递
g_szMutexName) ; // 名称
if (hMutexSuicide != NULL)
{
// 报告我们正在等待指令
std :: cout <<"Child waiting for suicide instructions. " << std :: endl;
//子进程进入阻塞状态,等待父进程通过互斥体发来的信号
WaitForSingleObject(hMutexSuicide, INFINITE) ;
//实验 1-3 步骤 4:将上句改为 WaitForSingleObject(hMutexSuicide, 0) ,重新编译执行
//dwMilliseconds[in]定时时间间隔,单位为milliseconds(毫秒).如果指定一个非零值,函数处于等待状态直到hHandle标记的对象被触发,或者时间到了。如果dwMilliseconds为0,对象没有被触发信号,函数不会进入一个等待状态,它总是立即返回。如果dwMilliseconds为INFINITE,对象被触发信号后,函数才会返回。// 准备好终止,清除句柄
std :: cout << "Child quiting." << std :: endl;
CloseHandle(hMutexSuicide) ;
}
}
int main(int argc, char* argv[] )
{
// 决定其行为是父进程还是子进程
if (argc>1 && :: strcmp(argv[1] , "child" )== 0)
{
Child() ;
}
else
{
Parent() ;
}
return 0;
}

四、实验结果与分析

   (1)编写基本的 Win32 Consol Application

运行结果:

 

   (2) 创建进程

步骤二运行结果:

 

进程相关属性:

 

 

步骤三运行结果:加入参数n(n<=5),nClone ID n~5的6-n个进程

 

Windows的任务管理器显示此6-n个进程。

 

 

步骤四运行结果:程序进入死循环,无限创建进程。结论:nClone的值控制着创建的进程数。变量的定义和初始化对程序的执行结果有影响,因为如果初始化在判定语句内,程序会受其影响!

 

   (3) 父子进程的简单通信及终止进程

步骤二运行结果:运行父子两个进程,在父进程中输入字符关闭子进程,形成父子进程的简单通信。

 

步骤三运行结果:由于传入的参数与child不同,所以一直执行Parent();函数,一直创建子进程。创建子进程时,格式化用于子进程的命令行,字符串“ child”将作为形参传递给子进程的 main 函数(sprintf(szCmdLine, "\"%s\"child" , szFilename) ;)。

 

步骤四运行结果:子进程一闪而过。/dwMilliseconds[in]定时时间间隔,单位为milliseconds(毫秒).如果指定一个非零值,函数处于等待状态直到hHandle标记的对象被触发,或者时间到了。如果dwMilliseconds为0,对象没有被触发信号,函数不会进入一个等待状态,它总是立即返回。如果dwMilliseconds为INFINITE,对象被触发信号后,函数才会返回。

 

步骤五:

CreateMutex()使用方法:

HANDLE CreateMutex(

LPSECURITY_ATTRIBUTESlpMutexAttributes, // 指向安全属性的指针

BOOLbInitialOwner, // 初始化互斥对象的所有者

LPCTSTRlpName // 指向互斥对象名的指针

);

创建一个互斥体(MUTEX)

返回值:

Long,如执行成功,就返回互斥体对象的句柄;零表示出错。会设置GetLastError。如果返回的是一个有效句柄,但指定的名字已经存在,GetLastError也会设为ERROR_ALREADY_EXISTS,bInitialOwner的值将会被忽略。如果调用者限制了权限,GetLastError将会返回ERROR_ACCESS_DENIED,这个时候应该使用OpenMutex函数。

参数类型及说明:

lpMutexAttributes SECURITY_ATTRIBUTES,指定一个SECURITY_ATTRIBUTES结构,或传递零值(将参数声明为ByVal As Long,并传递零值),表示使用不允许继承的默认描述符

bInitialOwner BOOL,如创建进程希望立即拥有互斥体,则设为TRUE。一个互斥体同时只能由一个线程拥有

lpName String,指定互斥体对象的名字。用vbNullString创建一个未命名的互斥体对象。如已经存在拥有这个名字的一个事件,则打开现有的已命名互斥体。这个名字可能不与现有的事件、信号机、可等待计时器或文件映射相符

 

OpenMutex()使用方法:

OpenMutex函数为现有的一个已命名互斥体对象创建一个新句柄。

函数功能:

函数原型: HANDLE OpenMutex(

DWORD dwDesiredAccess// access

BOOL bInheritHandle// inheritance option

LPCTSTR lpName // object name

);

参数:

dwDesiredAccess:

MUTEX_ALL_ACCESS 请求对互斥体的完全访问

MUTEX_MODIFY_STATE 允许使用 ReleaseMutex 函数

SYNCHRONIZE 允许互斥体对象同步使用

bInheritHandle : 如希望子进程能够继承句柄,则为TRUE

lpName :要打开对象的名字

返回值:

如执行成功,返回对象的句柄;零表示失败。若想获得更多错误信息,请调用GetLastError函数。

 

ReleaseMutex()使用方法:

ReleaseMutex函数的功能是释放互斥对象的控制权

函数原型:

BOOL WINAPI ReleaseMutex(

HANDLE hMutex

);

返回值:

BOOL,TRUE表示成功,FALSE表示失败。

参数表:

hMutex:HANDLE,制定一个互斥体的句柄。

 

WaitForSingleObject()使用方法:

 

等待函数可使线程自愿进入等待状态,直到一个特定的内核对象变为已通知状态为止。

WaitForSingleObject 函数

DWORD WaitForSingleObject(

HANDLE hObject,

          DWORD dwMilliseconds

);

第一个参数:hObject标识一个能够支持被通知/未通知的内核对象(前面列出的任何一种对象都适用)。

第二个参数:dwMilliseconds允许该线程指明,为了等待该对象变为已通知状态,它将等待多长时间。(INFINITE为无限时间量,INFINITE已经定义为0xFFFFFFFF(或-1))

传递INFINITE有些危险如果对象永远不变为已通知状态,那么调用线程永远不会被唤醒,它将永远处于死锁状态,不过,它不会浪费宝贵的C P U时间。

父子进程同步过程的一个大概描述:父进程创建“自杀”互斥程序体,参数值为TRUE,最初拥有,函数最后父进程释放互斥体所有权。子进程OpenMutex();打开互斥体获得句柄,WaitForSingleObject(hMutexSuicide, INFINITE) ;等待对象信号,如果dwMilliseconds为INFINITE,对象被触发信号后,函数才会返回。终止时,CloseHandle(hMutexSuicide) ;消除句柄

五、小结与心得体会

通过本实验,我学会使用 VC 的 Win32 Consol Application(控制台应用程序)创建进程并且观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟悉操作系统的进程概念,理解 Windows 进程的“一生”。通过阅读和分析实验程序,我学会了创建进程、观察进程、终止进程以及父子进程同步的基本程序设计方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/351211.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Python Supervisord 进程管理工具

Supervisord&#xff0c;用Python实现的一款非常实用的进程管理工具&#xff0c;在批量服务化管理时特别有效。 环境centospython2.6.6 安装 wget http://pypi.python.org/packages/source/s/supervisor/supervisor-3.0a10.tar.gztar zxvf supervisor-3.0a10.tar.gzcd superv…

Linux 进程管理

介绍一些 Linux 所提供的工具来进行进程的查看与控制&#xff0c;掌握这些工具让我们能在某些进程出现异常的时候及时查看相关的指标&#xff0c;从而解决问题。 一、进程查看 top:实时的查看进程的状态ps:静态查看当前的进程信息pstree:查看当前活跃进程的属性结构 1.1 top工…

Python实现的进程管理神器——Supervisor

文章目录 常用命令简介安装创建配置文件开机自启初试Web 界面配置文件子进程配置模板可用变量supervisorctl 命令Supervisor 组件卸载遇到的坑参考文献 常用命令 修改配置并重启子进程 vim /etc/supervisor/conf.d/xxx.conf supervisorctl reread supervisorctl update super…

Supervisor后台进程管理工具

Supervisor后台进程管理工具安装配置 一、安装及配置 1、Python liunx自带有了不需要安装&#xff08;没有的话需要安装&#xff09; 2、easy_install是setuptools包里带的一个命令 wget--no-check-certificate https://bootstrap.pypa.io/ez_setup.py -O - | sudo python 3、安…

Linux运维工具Supervisor(进程管理工具)

文章目录 一、介绍二、自带Web管理程序三、安装1、安装2、源码安装3、yum安装 四、配置文件五、启动六、设置开机启动七、查看 supervisord 是否在运行八、supervisorctl管理命令九、配置文件说明十、ini配置文件 举例说明十一、开启web页面管理程序十二、解决“unix:///tmp/su…

【Supervisor】Python 进程管理工具

Supervisor的安装配置与使用 一、简介 【1】Supervisor是Python开发的进程管理工具&#xff08;Client/Server系统&#xff09;&#xff0c;可以管理和监控Unix&#xff0c;Linux&#xff0c;Mac OS X 系统上的进程&#xff0c;无法运行在Windows上 【2】Supervisor官方版目前只…

Python supervisor 强大的进程管理工具

一、问题背景 1、背景 如何才能让一个进程摆脱终端&#xff0c;获得相对较长的生命周期&#xff1f; 2、后台(守护)、前台进程 什么是守护进程&#xff1f;通俗点讲就是后台跑着的进程&#xff0c;不会因为你关了终端服务就会随之停止&#xff0c;直到你把计算机的电源关闭…

进程管理工具supervisor的使用、常见报错问题处理

进程管理工具supervisor的使用、常见报错问题处理 1 安装2 简介2.1 supservisor自身提供三个命令&#xff1a;2.1.1 supervisorctl2.1.2 supervisord2.1.3 echo_supervisord_conf 2.2 配置文件2.3 重要事项2.4 查看supervisor的log日志 3 配置3.1 修改配置文件3.2 加载配置文件…

进程管理工具——Supervisord简介及安装

一、简介 Supervisor 是一个用 Python 写的进程管理工具&#xff0c;可以很方便的用来在 UNIX-like 系统&#xff08;不支持 Windows&#xff09;下启动、重启&#xff08;自动重启程序&#xff09;、关闭进程&#xff08;不仅仅是 Python 进程&#xff09; Supervisor 是一个 …

Supervisor进程管理详解

文章目录 1. supervisor简介2. supervisor安装2.1 安装方式2.2 验证 3. supervisor配置文件3.1 主配置文件3.2 子配置文件(program 配置)3.2.1 详细配置3.2.2 公司配置 4. 进程管理命令5. web管理&#xff08;不常用&#xff09;6. Supervisor配置systemctl服务7. Supervisor管…

Linux 中进程管理工具汇总

如果我们的Linux系统整个系统资源快要被耗尽时&#xff0c;我们是否能够找出那个最消耗系统资源的进程&#xff0c;然后删除该进程&#xff0c;让系统恢复正常呢&#xff0c;或者由于某个程序存在BUG&#xff0c;导致产生一系列的问题&#xff0c;有如何查找它并结束进程&#…

Supervisor安装与配置(Linux/Unix进程管理工具)

原文链接&#xff1a;http://blog.csdn.net/xyang81/article/details/51555473 Supervisor&#xff08;http://supervisord.org/&#xff09;是用Python开发的一个client/server服务&#xff0c;是Linux/Unix系统下的一个进程管理工具&#xff0c;不支持Windows系统。它可以很…

linux进程管理工具:supervisor

各种各样的程序运行情况中&#xff0c;或多或少都会有一些服务是用脚本跑起来的&#xff0c;我们通常的做法一般都是让其在后台运行&#xff0c;例如使用nohup&#xff0c;&等命令。 而这样的方法并不十分可靠&#xff0c;所以在这里推荐一个非常好用的进程管理工具&#x…

进程管理工具Supervisor

简介 Supervisor是一个客户端/服务器系统&#xff0c;允许用户在类UNIX操作系统上控制许多进程。它是基于python语言开发一个进程管理工具。 Supervisor的服务器端称为supervisord&#xff0c;主要负责在启动自身时启动管理的子进程&#xff0c;响应客户端的命令&#xff0c;重…

Supervisor 进程管理

一、简介 supervisor 是一个Python开发的、通用的进程管理程序。当程序中断时&#xff0c;supervisor能自动重启它&#xff0c;不再需要程序员或系统管理员自己编写代码来控制。 supervisor要求管理程序是非daemon程序&#xff0c;supervisor会把程序转成daemon程序&#xff0…

电脑技巧:进程管理工具Process Explorer介绍

目录 1、介绍 2、常用功能介绍 2.1 替代微软自带的任务管理器 2.2 查看当前系统中运行的进程 2.3 查看进程的详细信息 2.4 检索进程 2.5 监控操作系统的性能指标 2.6 获取Dump文件 2.7 进程操作功能 今天给大家推荐一款非常强大的进程管理工具Process Explorer&#xff0c;感兴…

进程管理工具

目录 一、进程管理工具(Supervisor) 简介 二、Supervisor安装与配置 介绍Supervisor 一、进程管理工具(Supervisor) 简介 Supervisor是用Python开发的一个client/server服务&#xff0c;是Linux/Unix系统下的一个进程管理工具&#xff0c;不支持Windows系统。它可以很方便的…

QLoRA:量化 LLM 的高效微调

此 repo 支持论文“QLoRA&#xff1a;量化 LLM 的高效微调”&#xff0c;旨在使对 LLM 研究的访问民主化。 QLoRA 使用bitsandbytes进行量化&#xff0c;并与 Hugging Face 的PEFT和transformers库集成。QLoRA 由华盛顿大学 UW NLP 小组的成员开发。 概述 我们介绍了 QLoRA&…

访问学者申请中4个难点解析

近年来&#xff0c;越来越多的学者希望通过申请成为访问学者来扩展他们的研究领域和学术交流。然而&#xff0c;访问学者申请过程中存在一些难点&#xff0c;下面知识人网来解析其中的4个难点。 首先&#xff0c;第一个难点是选择适合的研究机构。访问学者需要仔细考虑自己的研…

Fiddler抓包工具之高级工具栏中的Inspectors的使用

高级工具栏中的Inspectors的使用 Inspectors 页签允许你用多种不同格式查看每个请求和响应的内容。JPG 格式使用 ImageView 就可以看到图片&#xff0c;HTML/JS/CSS 使用 TextView 可以看到响应的内容。Raw标签可以查看原始的符合http标准的请求和响应头。Cookies标签可以看到…