精华内容
下载资源
问答
  • 通过pid查找进程task_struct结构体

    千次阅读 2018-04-12 20:23:58
    如何通过进程id查找进程的描述符task_struct?在实际的工作中,我的驱动中需要通过读取写进内存中的进程id值查找对应的进程是否还在运行,或者是已经退出。通过阅读内核代码,内核中已有相应的API函数来供我们使用。...

        如何通过进程id查找进程的描述符task_struct?在实际的工作中,我的驱动中需要通过读取写进内存中的进程id值查找对应的进程是否还在运行,或者是已经退出。通过阅读内核代码,内核中已有相应的API函数来供我们使用。下面是我在使用过程中的一些笔记总结。

        linux系统上运行的进程可能成百上千的,或者更多,如何能够快速的通过pid值反向的查找task_struct,内核的方法是通过Hash散列表的方式。下面结合3.16.7内核版本来分析pid hash表的实现。

    void __init pidhash_init(void)  

    {  

            unsigned int i, pidhash_size;  

      

            pid_hash = alloc_large_system_hash("PID", sizeof(*pid_hash), 0, 18,  

                                                                            HASH_EARLY | HASH_SMALL,  

                                                                            &pidhash_shift, NULL,  

                                                                            0, 4096);  

            pidhash_size = 1U << pidhash_shift;  

      

            for (i = 0; i < pidhash_size; i++)  

                    INIT_HLIST_HEAD(&pid_hash[i]);  

    }

        pidhash_init函数在系统启动时由start_kernel函数调用。Pid hash表的大小由运行机器的总内存数决定,范围在16~4096个之间。在之前老的内核(如2.6.12.6)pid hash表包含四个表,分别针对enum pid_type的四种不同类型PID的情况。

        进程创建时,是如何将task_struct与pid_hash散列表关联起来的?在copy_process函数中会判断参数pid指针是否等于init_struct_pid,如果不相等,就会调用alloc_pid函数分配一个新的struct pid类型的pid实例,并初始化。如果相等,说明是idle进程的创建。一般情况下,pid指针为空。下面看下alloc_pid函数的实现:

    struct pid *alloc_pid(struct pid_namespace *ns)  

    {  

            pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL);   

      

            tmp = ns;  

            pid->level = ns->level;  

            for (i = ns->level; i >= 0; i--) {  /*遍历pid namsespace*/

                    nr = alloc_pidmap(tmp);  

      

                    pid->numbers[i].nr = nr;  

                    pid->numbers[i].ns = tmp;  

                    tmp = tmp->parent;  

            }  

     

            for (type = 0; type < PIDTYPE_MAX; ++type)  

                    INIT_HLIST_HEAD(&pid->tasks[type]);  /*初始化每个id类型的散列表头*/

     

            upid = pid->numbers + ns->level;  

            spin_lock_irq(&pidmap_lock);  

            for ( ; upid >= pid->numbers; --upid) {  

                    hlist_add_head_rcu(&upid->pid_chain,  

                                                       &pid_hash[pid_hashfn(upid->nr, upid->ns)]);  

                    upid->ns->nr_hashed++;  

            }  

            spin_unlock_irq(&pidmap_lock);  

        参数ns参数是创建新进程时父进程task_struct描述符的命名空间指针nsproxy的pid namespace,一般情况下是指向init_pid_ns,如果在clone时候有指定CLONE_NEWPID标志,则会在copy_process中调用alloc_pid之前调用copy_namespaces创建一个新的pid namespace。

        函数首先调用kmem_cache_alloc从slab中分配pid内存。上面讲到如果clone时有指定标志CLONE_NEWPID的情况下,会创建一个新的pid namespace,此新建的pid namespace的parent指向父进程的pid namespace,相应的level也加一。这个新建的进程对于新创建的pid namespace和父进程的pid namespace,以及更初始的pid namespace都是可见的

        在第一个for循环中,从新创建PID namespace的level(此成员表示可以看到该进程的命名空间的数目)到0,给每个可见此进程的命名空间都分配一个局部的pid值。并将新分配的局部pid值nr赋给PID描述符的对应的命名空间numbers的nr字段,将pid namespace指针tmp赋给对应的命名空间numbers的ns字段。

        struct pid结构体中成员tasks是一个数组,每个数组成员是一个散列表的表头,对应于pid_type枚举中的一个id类型。在第二个for循环中,初始化tasks数组对应的每个id类型的散列表头。

        Pid结构体的成员numbers,虽然是一个长度为1的数组,但是因为它是在结构体的最后,可以根据pid所属的空间的个数分配更多的空间。numbers数组的大小由pid->level字段决定。Level值越大的命名空间级别越低,它能够被此pid的level值更小的命名空间看见,也就是说父命名空间能给看到子命名空间,反之子命名空间不能看见父命名空间。

        代码这里首先将upid指向此pid描述符的级别最低的命名空间,然后在for循环中遍历每层的命名空间,以当前pid namespace的进程id值nr和命名空间指针ns为key值,调用pid_hashfn函数生成pid_hash全局数组中的bucket id值,并将此进程链入此bucket id所在的hash散列表中。


        上面是alloc_pid函数分配一个新的pid描述符的大致过程,接着回到copy_process函数看看创建新进程的余下的和pid hash相关的代码。

    copy_process函数代码片段

    if (likely(p->pid)) {  

            init_task_pid(p, PIDTYPE_PID, pid);  

            if (thread_group_leader(p)) {  /*进程是线程组的组长*/

                    init_task_pid(p, PIDTYPE_PGID, task_pgrp(current));  

                    init_task_pid(p, PIDTYPE_SID, task_session(current));  

     

                    attach_pid(p, PIDTYPE_PGID);  

                    attach_pid(p, PIDTYPE_PGID);   

            } else {  

     

            }  

            attach_pid(p, PIDTYPE_PID);  /*PIDTYPE_PID类型的pid插入到相应的链表中*/

    }

        如果前面alloc_pid创建新的pid成功或者本身没有指定CLONE_NEWPID标志,就会进入上述代码片段执行。前面讲到枚举类型pid_type的不同id类型,在我分析的新内核(3.16.7)中是三种:

    PIDTYPE_PID     对应进程PID

    PIDTYPE_PGID    进程组领头进程PID

    PIDTYPE_SID    会话领头进程PID

        首先调用函数init_task_pid初始化新创建进程的类型PIDTYPE_PID的pid实例,如果此新创建的进程是线程组的组长,则初始化此进程的PIDTYPE_PGID类型和PIDTYPE_SID类型的实例,并且调用attach_pid函数将此进程进行Hash,加入到已经初始化好的pid_hash对应bucket的散列表中。

        这样就建立起了一个双向链表的关系,进程可以通过task_struct的task->pids[type]的成员pid访问pid实例,pid实例也可以通过遍历tasks[type]链表来查找进程task_struct。

        经过上面的分析,一个进程可以属于多个不同的命名空间,同一个进程在不同的命名空间中有不同的局部pid值,多个进程task_struct可以共用一个pid描述符。


    展开全文
  • Linux中由进程PID查找进程

    千次阅读 2013-11-24 11:51:24
    反过来 ,相同通过PID查找进程名则没有相关命令。  在linux根目录中,有一个/proc的VFS(虚拟文件系统),系统当前运行的所有进程都对应于该目录下的一个 以进程PID命名的文件夹 ,其中存放进程运行的N多信息。其中...

    Liunx中 通过进程名查找进程PID可以通过 pidof [进程名] 来查找。反过来 ,相同通过PID查找进程名则没有相关命令。

            在linux根目录中,有一个/proc的VFS(虚拟文件系统),系统当前运行的所有进程都对应于该目录下的一个 以进程PID命名的文件夹 ,其中存放进程运行的N多信息。其中有一个status文件,cat显示该文件, 第一行的Name 即为进程名

    模块

       ------------------------------------------------------------------------- 

    于是 。可以编写一个脚本,根据输入PID,输出其对应status文件中的的该字段即可

    【Shell脚本】如下

    #!/bin/bash
    #nameof [pid]
    usage()
    {
    echo "Usage: ./nameof [pid]"
    }
    if [ $# -ne 1 ]
    then
    {
    usage
    exit 0
    }
    fi
    
    pid=$1
    if [ -e /proc/$pid ] ; then
    {
    exec grep "Name:" /proc/$pid/status|awk '{print $2}'
    }
    else
    { 
    echo "`basename $0`: Pid $pid is not running!"
    exit
    }
    fi

    展开全文
  • linux查询进程(process)的pid

    使用命令:

    ss -l -p -n | grep 要找的端口号

    比如像这样:

    现在可以看到pid为8846

    之后就可以通过pid来进行其他的操作了

    展开全文
  • 根据pid查找进程运行路径

    千次阅读 2016-02-29 15:51:50
    运维的时候经常忘了进程的运行路径,需要根据pid查找路径 [root@bogon ~]# ll /proc/1574/exe lrwxrwxrwx. 1 root root 0 2?. 29 15:33 /proc/1574/exe -> /bin/bash(绝对路径) [root@bogon ~]#

    运维的时候经常忘了进程的运行路径,需要根据pid查找路径

    [root@bogon ~]# ll /proc/1574/exe
    lrwxrwxrwx. 1 root root 0 2?. 29 15:33 /proc/1574/exe -> /bin/bash(绝对路径)
    [root@bogon ~]# 

    展开全文
  • Windows根据TCP端口号查找进程PID再kill进程

    千次阅读 多人点赞 2019-05-14 23:56:11
    Windows根据TCP端口号查找进程PID再kill进程 Windows环境下,有时候TCP端口莫名其妙的被占用,导致正常的网络端口绑定失败,比如Android开发中,adb无法识别,有时候原因就是端口被占用。Java开发中,端口在占用...
  • 根据进程名字查找pid

    千次阅读 2016-10-16 14:00:04
    反过来 ,相同通过PID查找进程名则没有相关命令。在linux根目录中,有一个/proc的VFS(虚拟文件系统),系统当前运行的所有进程都对应于该目录下的一个以进程PID命名的文件夹,其中存放进程运行的N多信息。其中有一个...
  • 反过来 ,相同通过PID查找进程名则没有相关命令。 在linux根目录中,有一个/proc的VFS(虚拟文件系统),系统当前运行的所有进程都对应于该目录下的一个 以进程PID命名的文件夹 ,其中存放进程运行的N多信息。其中有...
  • 通过pid获取进程详细

    千次阅读 2019-03-18 13:51:47
    1 通过top命令获取所有在运行的程序,同时可以查看到对应的PID...2 通过PID获取进程信息 ll /proc/PID(每启动一个新进程,则会在proc下简历一个duiz对照的文件(名称为PID)。 cwd进程所在目录,exe进程类型 ...
  • linux c pid获取进程进程名获取pid

    千次阅读 2020-01-29 13:08:11
    反过来 ,相同通过PID查找进程名则没有相关命令。 在linux根目录中,有一个/proc的VFS(虚拟文件系统),系统当前运行的所有进程都对应于该目录下的一个 以进程PID命名的文件夹 ,其中存放进程运行的N多信息。其中有一...
  • tatus文件,第一行的Name即为进程名,C...反过来 ,相同通过PID查找进程名则没有相关命令。在linux根目录中,有一个/proc的VFS(虚拟文件系统),系统当前运行的所有进程都对应于该目录下的一个以进程PID命名的文件夹,其
  • 根据进程名查找进程PID

    千次阅读 2012-08-10 15:53:32
    #include using namespace std; //#include #include #include"tlhelp32.h" DWORD CheckModule(char* ...{//传入的参数是要搜索的进程名 HANDLE hSnapshot; PROCESSENTRY32 lppe; BOOL Find; BOOL Found; hSn
  • Linux通过PID查看进程完整信息

    万次阅读 2018-12-14 10:15:52
    通过top查看进程PID 这时,我们需要通过以下的方法来查看进程的详细信息: Linux在启动一个进程时,系统会在/proc下创建一个以PID命名的文件夹,在该文件夹下会有我们的进程的信息,其中包括一个名为exe的文件...
  • 根据进程号(PID)查找进程的所在目录

    千次阅读 2020-04-28 11:24:05
    cd /proc/6482 ls -ail cwd -> 进程目录 如图中cwd -> /home/XXX/tomcat8.5/bin
  • 使用ps -ef命令确定要杀死进程PID ps -ef | grep chrome 或者 ps -aux | grep chrome kill 命令的执行原理是这样的,kill 命令会向操作系统内核发送一个信号(多是终止信号)和目标进程PID,然后系统内核根据...
  • linux查找进程pid,并且kill

    千次阅读 2019-10-23 14:51:04
    比如查找与python相关的进程pid $ ps -ef | grep python 就会输出 这样就可以很容易看到,程序 python /home/chencancan/PThyroidC/preprocess/extract_patches.py 的pid为36273 如果要杀死这个进程,使用...
  • rem 查找18888对应的进程记录,并输出到pid....rem 查找进程记录,提取第5列的值,并终止进程,for 默认会已空格,制表符,;等进行字符串分割 for /f "tokens=5" %%i in (%root%\pid.txt) do ( taskkill /pid %%i /F goto :e
  • dos 命令查找进程pid pid_find.bat

    千次阅读 2014-12-22 00:07:02
    //zz//######################...pid-find.bat zz@2014-12-22 00:23:30 没什么特别的,linux下玩了下脚本 想起到dos上来玩玩bat脚本, for /f 和 |find /i 的使用 @title dos_find_pid @color 0a @echo just an
  • android通过进程查找PID

    千次阅读 2014-09-22 15:10:47
    需要通过(部分)进程查找PID,然后可以kill指定的进程了. 读取/proc/PID/cmdline 为完整进程名,即PS命令可以看到的进程名. 读取/proc/PID/stat 为进程各种信息.包括PID,部分进程名(不超过15字节),以及...
  • 在windows系统环境下 ,通过进程名称查看该进程是否存在,存在的话 taskkill结束进程。 public class ProcessUtil { private static final Log logger = LogFactory.getLog(ProcessUtil.class); ...
  • 首先建立一个while循环可执行文件 #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; int main(int argc, char *argv[]) { while(1); } 编译运行: ...查看进程编号: $...
  • 使用linux操作系统,难免遇到一些软件"卡壳"的问题,这时就需要使用linux下强大的kill命令来结束相关进程。这在linux系统下是极其容易的事情,你只需要kill xxx即可,这里xxx代表与此软件运行相关...
  • awk 的简单使用-查找进程pid

    千次阅读 2015-08-20 12:08:31
    在linux下我一般只用grep 和 find工具进行查找 这些工具虽然强大但是我们平时只会用到几个常用的,那些什么什么详解,什么什么的完全解析的文章我们根本就不适用,只要学会几条就好了。 先说一下我常用的grep 命令...
  • 通过PID获取进程路径和进程名的两种方法 分类: 编程技术2012-04-25 10:54 3220人阅读 评论(3) 收藏 举报 extensionpathnulltokenextwindows 通过PID获取进程路径和进程名,使用了psapi.h类,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 99,040
精华内容 39,616
关键字:

怎么通过pid查找进程