一、/var/run/*.pid文件的作用
防止启动多个进程副本
二、/var/run/*.pid文件是怎么产生的
/* Our process ID and Session ID */
pid_t pid, sid;
/* Fork off the parent process */
pid = fork();
if(pid < 0)
{
exit(EXIT_FAILURE);
}
/* If we got a good PID, then
we can exit the parent process. */
if(pid > 0)
{
FILE *file = fopen(pidPath, "w");
fprintf(file, "%d", pid);
fclose(file);
exit(EXIT_SUCCESS);
}
/* Change the file mode mask */
umask(0);
/* Create a new SID for the child process */
sid = setsid();
if(sid < 0)
{
/* Log the failure */
exit(EXIT_FAILURE);
}
三、/var/run/*.pid文件的内容
cat /var/run/*.pid 可以看到,只有一行内容:该进程的ID;
四、应用:通过*.pid文件,检查进程状态
//pidPath = "/var/run/*.pid"
int ret = -1;
size_t length = 0;
uint8_t procPath[PATH_MAX] = {0};
FILE *file = fopen(pidPath, "r");
if(!file)
{
return 0;
}
fseek(file, 0L, SEEK_END);
length = ftell(file);
fseek(file, 0L, SEEK_SET);
uint8_t *buffer = (uint8_t *)calloc(length + 1, sizeof(uint8_t));
if(!buffer)
{
ret = 0;
goto Cleanup;
}
fread(buffer, sizeof(uint8_t), length, file);
snprintf(procPath, sizeof(procPath), "/proc/%s/status", buffer);
if(access(procPath, F_OK) != 0)
{
ret = 0;
goto Cleanup;
}
Cleanup:
if(buffer)
{
free(buffer);
}
fclose(file);
return ret;
上述代码中我们看到/proc/pid(进程号)/status
那么我们顺便解析一个进程的status:
Name: ProcName
Umask: 0022---------------------------------表示进程新建文件,目录的权限
State: D (disk sleep)-----------------------表示此时线程处于sleeping,并且是uninterruptible状态的wait。
Tgid: 151-------------------------------------线程组的主pid为151。
Ngid: 0----------------------------------------进程所属的NUMA id
Pid: 151--------------------------------------线程自身的pid为151。
PPid: 1---------------------------------------线程组是由init进程创建的(父进程)。
TracerPid: 0---------------------------------ptrace对应的进程id
Uid: 0 0 0 0----------------------------------实际用户id,指的是进程执行者是谁
Gid: 0 0 0 0
FDSize: 32---------------------------------表示到目前为止进程使用过的描述符总数。
Groups: 0 10
VmPeak: 9392 kB--------------------------虚拟内存峰值大小。
VmSize: 9392 kB--------------------------当前使用中的虚拟内存,小于VmPeak。
VmLck: 0 kB-------------------------------------PG_mlocked属性的页面重量,常被mlock()置位;
VmPin: 0 kB-------------------------------------不可被移动的Pined Memory内存大小
VmHWM: 3508 kB-----------------------------RSS峰值。
VmRSS: 3508 kB-----------------------------RSS实际使用量=RSSAnon+RssFile+RssShmem。
RssAnon: 0 kB---------------------------匿名RSS内存大小
RssFile:0 kB-------------------------------文件RSS内存大小
RssShmem: 0 kB------------------------------共享内存RSS内存大小
VmData: 4240kB--------------------------进程数据段共366648KB。
VmStk: 136 kB------------------------------进程栈一共132KB。
VmExe: 256 kB-------------------------------进程text段大小84KB。
VmLib: 4528 kB----------------------------进程lib占用11488KB内存。
VmPTE: 1220 kB----------------------------进程也表项Page Table Entries内存使用量
VmPMD: 0 kB--------------------------------进程PMD内存使用量
VmSwap: 0 kB-------------------------------进程swap使用量
Threads: 40-------------------------------进程中一个40个线程。
SigQ: 0/3142------------------------------进程信号队列最大3142,当前没有pending状态的信号。
SigPnd: 0000000000000000------------------信号队列中处于pending状态的进程,目前无,所以位图为0。
ShdPnd: 0000000000000000-----------------线程组中处于pending状态的位图
SigBlk: 0000000000000000--------------------处于阻塞(blocked)状态的洗脑位图
SigIgn: 0000000000000006------------------被忽略的信号,对应信号为SIGINT和SIGQUIT,这两个信号产生也不会进行处理。
SigCgt: 0000000180000800------------------已经产生的信号位图,对应信号为SIGUSR2、以及实时信号32和33。
CapInh: 0000000000000000------------------表示能被子进程继承的能力
CapPrm: 0000001fffffffff--------------------------进程允许被使用的能力
CapEff: 0000001fffffffff----------------------------进程要使用某个特权时,系统会检查cap_effective对应为是否有效,cap_effective是cap_permitted子集
CapBnd: 0000001fffffffff--------------------------表示进程能获得的最大能力
CapAmb: 0000000000000000
Cpus_allowed: 1---------------------------仅在第1个cpu上执行。
Cpus_allowed_list: 0
voluntary_ctxt_switches: 2377-------------线程主动切换2377次
nonvoluntary_ctxt_switches: 5--------------线程被动切换5次。
关注公众号【林学长和宋学姐】,分享程序员和程序媛的日常并且回复关键字:QT播放器项目,Zigbee,matlab等关键字,获取大量学习资料!