Linux环境下编程,经常会遇到进程控制的问题,例如fork,exec以及查找,杀死进程。
下面是一些比较实用的进程控制小程序:
1.根据名称查找返回进程PID
#define PS_COMMAND "ps|grep "
//注意:不是所有平台都支持"ps -ax" 因此这里使用比较通用的"ps"
#define SCAN(buf) (sscanf(buf,"%d %s %s %s %s",pid,s[0],s[1],s[2],cmd) == 5)
int* lookupAndKillProc(char* name)
{
if(name == NULL) return -1;
FILE *fp = NULL;
char buf[256], cmd[200], s[3][32],procPID[10];
pid_t pid = 0;
int i = 0,pidCount = 0;
int max_pid = 5;
pid_t pids[max_pid];
// ps|grep name
strcpy(cmd,PS_COMMAND);
strcat(cmd,name);
//通过打开管道,接收cmd运行返回的结果
if ((fp = popen(cmd, "r")) == NULL){
return NULL;
}else{
while (pidCount < max_pid && fgets(buf, sizeof(buf), fp)){
sscanf(&buf[9],"%d",&pid); // PID 在buf[9]~buf[14]
pids[pidCount++] = pid; //可能有多个同名的进程存在
}
pclose(fp);
}
return pids;
}
2. 创建进程,执行命令
这里通过fork两次,避免子进程成为僵尸进程的可能。
父进程fork产生子进程后,在父进程未结束的情况下,kill子进程,则这个子进程会成为僵尸进程,
必须等父进程结束后,子进程有init进程领养,这是init进程会清楚僵尸进程,此时子进程才会彻底清除。
int runConmand(){
pid_t pid,returnPID;
int status;
//signal(SIGCHLD, sig_chld);
if((pid=fork())<0){
return -1;
}else if(pid == 0){ //first child
if((pid = fork())<0){
return -1;
}else if(pid > 0){ // parent of second child == firstchild
exit(0);
}
//sleep(2);
//in second child progress
char *suiteId = malloc(2);
if(suiteId != NULL) sprintf(suiteId,"%d",id);
if(execl("/system/bin/runNams","runNams","-runMidlet",suiteId,NULL)<0){
return -1;
}
//exit(0);
}
//in parent progress,wait for the first child
if(waitpid(pid,&status,0) != pid){
return -1;
}
// 注意: 这里返回的是第一次fork的进程ID,如何得到第二次fork的进程ID?
return pid;
}
3.杀死指定PID的进程
int killProc(int id){
int pid = id;
if(pid < 0){
return -1;
}else{
//kill(pid,SIGKILL); //kill,ps->exist
char cmd[20];
strcpy(cmd,"kill -9 ");
char str_pid[10];
sprintf(str_pid,"%d",pid);
strcat(cmd,str_pid);
system(cmd); //使用system命令执行kill -9 xxx,彻底结束进程
return 0;
}
}