Linux 下获取进程PID

      Linux查询pid有多种方式,可通过遍历/proc目录下进程运行信息及shell ps命令

1. 遍历/proc目录

    Linux下每个运行的进程都会在/proc目录下建立该进程pid目录,/proc/pid 目录下有 status, cmdline等描述进程运行参数,状态等信息. 运行可能没有命令行参数,cmdline文件可能为空. 我们选择 status 文件,比较 status 中 Name 字段即可

    

// 根据进程名称查找pid
pid_t GetPidByName(const char *pName)
{
 DIR *pdir = NULL;
 struct dirent *pde = NULL;
 
 FILE *pf = NULL;
 char buff[128];
 pid_t pid;
 char szName[128];
 
 // 遍历/proc目录下所有pid目录
 pdir = opendir("/proc");
 if (!pdir)
 {
  perror("open /proc fail.\n");
  return -1;
 }
 
 while ((pde = readdir(pdir)))
 {
  if ((pde->d_name[0] < '0')|| (pde->d_name[0] > '9'))
  {
   continue;
  }
  
  // 读取 /proc/$pid/status文件
  sprintf(buff, "/proc/%s/status", pde->d_name);
  pf = fopen(buff, "r");
  if (pf)
  {
   fgets(buff,sizeof(buff),pf);
   fclose(pf);
   
   sscanf(buff,"%*s %s",szName); // 跳过Name:字段,获取进程名称
   pid=atoi(pde->d_name);
   
   if(strcmp(szName,pName)==0)
   {
    closedir(pdir);
    return pid;
   }
  }
 }
 
 closedir(pdir);
 return 0;
}

二. ps 命令

     进程名截断

    ps

    通过上述截图发现,如果进程名称过长,会被截断,这种情况下无法通过status匹配进程名称,而ps命令却完美解决上述问题,可以通过管道接收shell执行结果

    

int FindPidByName(const char *pName)
{
	int szPid=-1;

	char szProQuery[256];
	sprintf(szProQuery,"ps -ef|grep '%s'|grep -v 'grep'|awk '{print $2}'",pName);  // 打开管道,执行shell命令

	FILE *fp=popen(szProQuery,"r");
	char szBuff[10];

	while(fgets(szBuff,10,fp)!=NULL) // 逐行读取执行结果
	{
		szPid=atoi(szBuff);
		break;
	}

	pclose(fp); // 关闭管道指针,不是fclose()很容易混淆
	return szPid;
}

猜你喜欢

转载自tcspecial.iteye.com/blog/2063852