Linux 进程 ID(PID)查看 / 获取方法
<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>Linux 中简单的找出进程 ID(PID)的 4 个方法<ul class="second_class_ul"><li>进程 ID</li><li>方法 1: pidof 命令</li><li>方法 2: pgrep 命令</li><li>方法 3: pstree 命令</li><li>方法 4: ps 命令</li></ul></li><li>Linux 下获得进程 id 和进程名字<ul class="second_class_ul"></ul></li><li>Linux 下获取当前进程 ID、进程名、进程路径<ul class="second_class_ul"></ul></li><li>Linux 下通过进程名、ID、端口号查看进程信息<ul class="second_class_ul"><li>1. 通过进程名查看</li><li>2. 通过进程 ID 查看</li><ul class="third_class_ul"><li>2.1 通过进程 ID 查询端口占用</li><li>2.2 通过进程 ID 查询进程名</li></ul><li>3. 通过端口号查看</li><ul class="third_class_ul"></ul><li>4. 根据进程 ID 杀死进程</li><ul class="third_class_ul"></ul></ul></li><li>在 Linux 环境中如何获取进程 id<ul class="second_class_ul"></ul></li><li>Linux查看进程PID以及杀掉进程的方法<ul class="second_class_ul"><li>查看进程PID</li><ul class="third_class_ul"><li>PS命令</li><li> ps -le命令</li><li>查找父进程</li></ul><li>杀死进程</li><ul class="third_class_ul"></ul></ul></li></ul></div><p class="maodian"></p><h2>Linux 中简单的找出进程 ID(PID)的 4 个方法</h2><p>我们查询 PID 主要是用来杀死一个没有响应的程序,它类似于 Windows 任务管理器一样。 Linux GUI 也提供相同的功能,但 CLI 是执行 <code>kill</code> 操作的有效方法。</p>
<p class="maodian"></p><h3>进程 ID</h3>
<p>PID 代表进程标识号 process identification,它在大多数操作系统内核(如 Linux、Unix、macOS 和 Windows)中使用。它是在操作系统中创建时自动分配给每个进程的唯一标识号。一个进程是一个正在运行的程序实例。</p>
<p>除了 init 进程外其他所有的进程 ID 每次都会改变,因为 init 始终是系统上的第一个进程,并且是所有其他进程的父进程。它的 PID 是 1。</p>
<p>PID 默认的最大值是 <code>32768</code>。可以在你的系统上运行 <code>cat /proc/sys/kernel/pid_max</code> 来验证。在 32 位系统上,<code>32768</code> 是最大值,但是我们可以在 64 位系统上将其设置为最大2^{22}(约 4 百万)内的任何值。</p>
<p>你可能会问,为什么我们需要这么多的 PID?因为我们不能立即重用 PID,这就是为什么。另外为了防止可能的错误。</p>
<p>系统正在运行的进程的 PID 可以通过使用 <code>pidof</code>、<code>pgrep</code>、<code>ps</code> 和 <code>pstree</code> 命令找到。</p>
<p class="maodian"></p><h3>方法 1: pidof 命令</h3>
<p><code>pidof</code> 用于查找正在运行的程序的进程 ID。它在标准输出上打印这些 id。为了演示,我们将在 Debian 9(stretch)系统中找出 Apache2 的进程 ID。</p>
<div class="dxycode"><pre class="brush:bash;">\# pidof apache2
3754 2594 2365 2364 2363 2362 2361</pre></div>
<p>从上面的输出中,你可能会遇到难以识别进程 ID 的问题,因为它通过进程名称显示了所有的 PID(包括父进程和子进程)。因此,我们需要找出父 PID(PPID),这是我们要查找的。它可能是第一个数字。在本例中,它是 <code>3754</code>,并按降序排列。</p>
<p class="maodian"></p><h3>方法 2: pgrep 命令</h3>
<p><code>pgrep</code> 遍历当前正在运行的进程,并将符合选择条件的进程 ID 列到标准输出中。</p>
<div class="dxycode"><pre class="brush:bash;">\# pgrep apache2
2361
2362
2363
2364
2365
2594
3754</pre></div>
<p>这也与上面的输出类似,但是它将结果从小到大排序,这清楚地说明父 PID 是最后一个。在本例中,它是 <code>3754</code>。</p>
<p><strong>注意:</strong> 如果你有多个进程的进程 ID,那么在使用 <code>pidof</code> 和 <code>pgrep</code> 识别父进程 ID 时就可能不会很顺利。</p>
<p class="maodian"></p><h3>方法 3: pstree 命令</h3>
<p><code>pstree</code> 将运行的进程显示为一棵树。树的根是某个 pid,如果省略了 pid 参数,那么就是 init。如果在 <code>pstree</code> 命令中指定了用户名,则显示相应用户拥有的所有进程。</p>
<p><code>pstree</code> 会将相同的分支放在方括号中,并添加重复计数的前缀来可视化地合并到一起。</p>
<div class="dxycode"><pre class="brush:bash;">\# pstree -p | grep "apache2"
|- apache2(3754) -|-apache2(2361)
| |-apache2(2362)
| |-apache2(2363)
| |-apache2(2364)
| |-apache2(2365)
| `-apache2(2594)</pre></div>
<p>要单独获取父进程,请使用以下格式。</p>
<div class="dxycode"><pre class="brush:bash;">\# pstree -p | grep "apache2" | head -1
|- apache2(3754) -|-apache2(2361)</pre></div>
<p><code>pstree</code> 命令非常简单,因为它分别隔离了父进程和子进程,但这在使用 <code>pidof</code> 和 <code>pgrep</code> 时命令不容易做到。</p>
<p class="maodian"></p><h3>方法 4: ps 命令</h3>
<p><code>ps</code> 显示活动进程的选择信息。它显示进程 ID(<code>pid</code>=PID)、与进程关联的终端(<code>tname</code>=TTY)、以 <code>hh:mm:ss</code> 格式(<code>time</code>=TIME)显示的累计 CPU 时间、以及执行名(<code>ucmd</code> = CMD)。输出默认是未排序的。</p>
<div class="dxycode"><pre class="brush:bash;">\# ps aux | grep "apache2"
www-data 2361 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start
www-data 2362 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start
www-data 2363 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start
www-data 2364 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start
www-data 2365 0.0 0.4 302652 8400 ? S 06:25 0:00 /usr/sbin/apache2 -k start
www-data 2594 0.0 0.4 302652 8400 ? S 06:55 0:00 /usr/sbin/apache2 -k start
root 3754 0.0 1.4 302580 29324 ? Ss Dec11 0:23 /usr/sbin/apache2 -k start
root 5648 0.0 0.0 12784 940 pts/0 S+ 21:32 0:00 grep apache2</pre></div>
<p>从上面的输出中,我们可以根据进程的启动日期轻松地识别父进程 ID(PPID)。在此例中,apache2 启动于 <code>Dec 11</code>,它是父进程,其他的是子进程。apache2 的 PID 是 <code>3754</code>。</p>
<p class="maodian"></p><h2>Linux 下获得进程 id 和进程名字</h2>
<p>编程过程中,有的时候需要通过进程 id 来得到进程的名字,或则通过进程的名字来得到 id。通过 shell 可以很容易得到,这里通过代码来实现。</p>
<p>通过进程名字得到进程 id。</p>
<div class="dxycode"><pre class="brush:bash;">pid_t getProcessPidbyName(char *name)
{
FILE *fptr;
char *buf = new char;
char cmd = {'\0'};
pid_t pid = -1;
sprintf(cmd,"pidof %s",name);
if((fptr = popen(cmd,"r")) != NULL)
{
if(fgets(buf,255,fptr) != NULL)
{
pid = atoi(buf);
printf("pid = %d\n",pid);
}
}
pclose(fptr);
delete buf;
return pid;
}</pre></div>
<p>这里的传入参数 name 是进程的名字,不是它的绝对路径名。</p>
<p>通过进程 id 得到进程的文件路劲名字,进程存在的绝对路径名。</p>
<div class="dxycode"><pre class="brush:bash;"> bool getPathNamebyPid(pid_t pid,char *name)
{
FILE *fptr;
bool bret = false;
char cmd = {'\0'};
sprintf(cmd,"readlink /proc/%d/exe",pid);
if((fptr = popen(cmd,"r")) != NULL)
{
if(fgets(name,255,fptr) != NULL)
{
printf("the path name is %s.\n",name);
bret = true;
}
}
pclose(fptr);
return bret;
}</pre></div>
<p>这里得到的是进程的绝对路径名,传入的参数,需要在外部为其开辟空间,用完需要释放。</p>
<p>通过文件的绝对路径名自然就很容易得到进程的名字。</p>
<div class="dxycode"><pre class="brush:bash;">bool getProcessNamebyPathName(const char* pathName,char* name)
{
memset(name,'\0',255);
const char* pos = strrchr(pathName,'/');
if(pos == 0)
{
strcpy(name,pathName);
}
else
{
strcpy(name,pos+1);
}
return true;
}</pre></div>
<p>就是从绝对路径名中拿出进程名。传入参数 pathName,传出参数 name 需要在外部开辟空间。</p>
<p>结合前面博文,就能够根据进程名,判断是否存在同名进程。</p>
<p class="maodian"></p><h2>Linux 下获取当前进程 ID、进程名、进程路径</h2>
<div class="dxycode"><pre> #include
#include
#include
int main()
{
pid_t pid = getpid();
char strProcessPath = {0};
if(readlink("/proc/self/exe", strProcessPath,1024) <=0)
{
return -1;
}
char *strProcessName = strrchr(strProcessPath, '/');
if(!strProcessName)
{
printf("当前进程ID:%d\n", pid);
printf("当前进程名:\n");
printf("当前进程路径:%s\n", strProcessPath);
}
else
{
printf("当前进程ID:%d\n", pid);
printf("当前进程名:%s\n", ++strProcessName);
printf("当前进程路径:%s\n", strProcessPath);
}
return 0;
}</pre></div>
<p class="maodian"></p><h2>Linux 下通过进程名、ID、端口号查看进程信息</h2>
<p class="maodian"></p><h3>1. 通过进程名查看</h3>
<p>以查看 <code>sshd</code> 进程名为例,执行以下命令:</p>
<div class="dxycode"><pre class="brush:bash;">ps -ef | grep sshd</pre></div>
<p>返回结果如下:</p>
<p style="text-align:center"><img alt="" src="https://zhuji.jb51.net/uploads/allimg/20250527/2-25052G1450a42.png" width="700" /></p>
<p>每一列的含义可以通过如下指令查看:</p>
<p style="text-align:center"><img alt="" src="https://zhuji.jb51.net/uploads/allimg/20250527/2-25052G1450a39.png" width="700" /></p>
<p class="maodian"></p><h3>2. 通过进程 ID 查看</h3>
<p class="maodian"></p><h4>2.1 通过进程 ID 查询端口占用</h4>
<p>以 <code>sshd</code> 进程为例,其进程 PID 为 522</p>
<p>若系统中没有 <code>netstat</code> 命令,可使用以下命令进行安装:</p>
<div class="dxycode"><pre class="brush:bash;">sudo apt-get install net-tools</pre></div>
<p>执行以下命令查询端口占用情况:</p>
<div class="dxycode"><pre class="brush:bash;">netstat-nap|grep522</pre></div>
<p>若要查看 <code>root</code> 用户进程,则需添加 <code>sudo</code> 指令,命令如下:</p>
<div class="dxycode"><pre class="brush:bash;">sudo netstat -nap|grep 522</pre></div>
<p>返回结果如下:</p>
<p style="text-align:center"><img alt="" src="https://zhuji.jb51.net/uploads/allimg/20250527/2-25052G1450bW.png" width="700" /></p>
<p>每一列的含义可以通过如下指令查看:</p>
<p style="text-align:center"><img alt="" src="https://zhuji.jb51.net/uploads/allimg/20250527/2-25052G14510527.png" width="700" /></p>
<p>结合上述图片可知,查询的 ID 为 522 的进程名称为 <code>sshd</code>,与上一步的结果完全吻合。</p>
<p class="maodian"></p><h4>2.2 通过进程 ID 查询进程名</h4>
<p>以 <code>sshd</code> 进程为例,其进程 PID 为 522</p>
<p>执行以下命令查询进程名:</p>
<div class="dxycode"><pre class="brush:bash;">ps-ef|grep522</pre></div>
<p>返回结果如下:</p>
<p style="text-align:center"><img alt="" src="https://zhuji.jb51.net/uploads/allimg/20250527/2-25052G14510457.png" width="700" /></p>
<p class="maodian"></p><h3>3. 通过端口号查看</h3>
<p>以 <code>sshd</code> 进程为例,从前面步骤可知 <code>sshd</code> 的端口号为 22,如下图所示:</p>
<p style="text-align:center"><img alt="" src="https://zhuji.jb51.net/uploads/allimg/20250527/2-25052G14510100.png" width="700" /></p>
<p>输入以下指令查询:</p>
<div class="dxycode"><pre class="brush:bash;">netstat -tunlp | grep 22</pre></div>
<p>若要查看 <code>root</code> 用户进程,则需添加 <code>sudo</code> 指令:</p>
<div class="dxycode"><pre class="brush:bash;">sudo netstat -tunlp | grep 22</pre></div>
<p>返回结果如下:</p>
<p style="text-align:center"><img alt="" src="https://zhuji.jb51.net/uploads/allimg/20250527/2-25052G14510Q0.png" width="700" /></p>
<p class="maodian"></p><h3>4. 根据进程 ID 杀死进程</h3>
<p>若要杀死进程 ID 为 522 的进程,可执行以下命令:</p>
<div class="dxycode"><pre class="brush:bash;">sudo kill -9 522</pre></div>
<p>注意,该进程为 <code>ssh</code> 远程连接守护进程,不建议轻易执行此操作。若杀死该进程,将无法进行远程连接,需重启系统方可恢复。</p>
<p class="maodian"></p><h2>在 Linux 环境中如何获取进程 id</h2>
<p>Linux 系统中,每个进程都有对应的目录和文件,可以直接访问这些文件来获取进程信息,其中 PID 可以从进程的 /proc/PID/ 目录中的 status 或 cmdline 文件中找到。</p>
<p><strong>查看 /proc 文件系统</strong></p>
<div class="dxycode"><pre>cat /proc//status |grep'^Pid:'</pre></div>
<p><strong>代码实现获取进程 ID</strong></p>
<p>可以通过操作系统提供的 API 来实现。常见的方式是使用 头文件中的 getpid() 函数。</p>
<div class="dxycode"><pre>#include
#include
int main() {
// 获取当前进程的PID
pid_t pid = getpid();
std::cout << "PID of the current process: " << pid << std::endl;
return 0;
}</pre></div>
<p>如果你想根据进程名获取进程的 PID,通常需要使用操作系统提供的功能来遍历系统中的进程并匹配进程名。</p>
<p>在 Linux 系统中,可以使用 proc 文件系统来实现这个目的。</p>
<div class="dxycode"><pre>#include
#include
#include
#include
#include
#include
// 函数:根据进程名获取PID
pid_t get_pid_by_name(const std::string& process_name) {
pid_t pid = -1;
std::ifstream ifs("/proc/self/stat");
std::string line;
while (std::getline(ifs, line)) {
std::istringstream iss(line);
std::vector tokens{std::istream_iterator{iss},
std::istream_iterator{}};
if (tokens.size() < 2) {
continue;
}
std::string cmd = tokens;
// Remove parentheses from cmd (process name)
if (!cmd.empty() && cmd == '(' && cmd == ')') {
cmd = cmd.substr(1, cmd.size()-2);
}
if (cmd == process_name) {
pid = std::stoi(tokens);
break;
}
}
return pid;
}
int main() {
std::string process_name = "nginx";
pid_t pid = get_pid_by_name(process_name);
if (pid != -1) {
std::cout << "PID of process '" << process_name << "': " << pid << std::endl;
} else {
std::cout << "Process '" << process_name << "' not found." << std::endl;
}
return 0;
}</pre></div>
<p>这段代码在 Linux 环境下使用,依赖于 /proc 文件系统来获取进程信息。因此,在其他操作系统上(如Windows)可能无法直接运行或需要不同的实现方法。进程名在 /proc/self/stat 文件中被括号括起来,所以在比较时需要去除括号。该示例代码相对简单,实际应用中可能需要更复杂的逻辑来处理各种情况,如多个同名进程等。</p>
<p class="maodian"></p><h2>Linux查看进程PID以及杀掉进程的方法</h2>
<p class="maodian"></p><h3>查看进程PID</h3>
<p class="maodian"></p><h4>PS命令</h4>
<p>ps命令可以查看linux系统当前账号运行的所有进程,查看进程PID的命令格式为:</p>
<div class="dxycode"><pre class="brush:bash;">ps aux | grep</pre></div>
<p>其中,aux参数表示列出系统所有用户的所有进程,grep参数表示要查看的进程名称。具体例子如下:</p>
<p>#查看所有的python进程PID</p>
<div class="dxycode"><pre class="brush:bash;">ps aux | grep python</pre></div>
<p>或使用 ps aux |head -n 10 只展示前10条记录,方便查看列头含义</p>
<p style="text-align:center"><img alt="" src="https://zhuji.jb51.net/uploads/allimg/20250527/2-25052G14511H7.png" /></p>
<p class="maodian"></p><h4> ps -le命令</h4>
<p>"ps aux"命令可以看到系统中所有的进程,"ps -le"命令也能看到系统中所有的进程。由于 “-l” 选项的作用,所以 “ps -le” 命令能够看到更加详细的信息,比如父进程的 PID、优先级等 </p>
<p>或使用 ps -ef |head -n 10 只展示前10,条记录,方便查看列头含义</p>
<p style="text-align:center"><img alt="" src="https://zhuji.jb51.net/uploads/allimg/20250527/2-25052G14511250.png" /></p>
<p class="maodian"></p><h4>查找父进程</h4>
<p>要查看进程的<strong>父</strong>进程,可通过以下命令进行:</p>
<div class="dxycode"><pre class="brush:bash;">ps -o ppid= -p <进程的PID></pre></div>
<p class="maodian"></p><h3>杀死进程</h3>
<p>通过以下命令可强制杀死指定PID的进程:</p>
<div class="dxycode"><pre class="brush:bash;">kill -9 </pre></div>
<p>或者通过以下命令杀死包含所有<strong>该名称</strong>的进程(当前用户下的):</p>
<div class="dxycode"><pre class="brush:bash;">pkill -f 名称(如seed7)</pre></div>
<p><strong>附:在Linux服务器上跑Caffe、TensorFlow、pytorch之类的需要CUDA的程序时,强行Kill掉进程后发现显存仍然占用</strong></p>
<p>使用如下命令查看到top或者ps中看不到的进程,之后再kill掉:</p>
<div class="dxycode"><pre class="brush:bash;">fuser -v /dev/nvidia*</pre></div>
頁:
[1]