请教高手:C语言怎么知道一个进程是否存在(Linux下)

xuzhike 2006-05-23 10:38:36
我手动起了一个服务程序(如sipSer)--自己写的;然后我想在某个时刻通过另外一个C程序去查询该服务是否仍然在运行,我该怎么写啊
...全文
1404 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
fallinleave 2006-05-23
  • 打赏
  • 举报
回复
呵呵,网上找到的代码,凑合着看吧,刚才去吃饭了
fallinleave 2006-05-23
  • 打赏
  • 举报
回复
第二种办法是使用kvm_*()函数

--------------------------------------------------------------------------
/*
* gcc -Wall -DSOLARIS=6 -O3 -o getpid getpid.c -lkvm -lgen
*
* /opt/SUNWspro/SC5.0/bin/cc -DSOLARIS=7 -xarch=v9 -O -o getpid getpid.c -lkvm -lgen
*/

/*
* 必须定义这个宏
*/
#define _KMEMUSER

#include <stdio.h>
#include <stdlib.h>
#include <regexpr.h>
#include <sys/proc.h>
#include <kvm.h>
#include <fcntl.h>

/*
static void argv_free ( char ** argv )
{
size_t i;
for ( i = 0; argv[i] != NULL; i++ )
{
free( argv[i] );
argv[i] = NULL;
}
free( argv );
}
*/

static pid_t getpidbyname ( char *name, pid_t skipit )
{
kvm_t *kd;
int error;
char **argv = NULL;
char *p_name = NULL;
pid_t pid = -1;
char expbuf[256];
char regexp_str[256];
struct user *cur_user;
struct proc *cur_proc;
struct pid p;

sprintf( regexp_str, "^.*%s$", name );
/*
* 正则表达式
*/
if ( compile( regexp_str, expbuf, expbuf + 256 ) == NULL )
{
perror( "compile" );
return( -1 );
}
if ( ( kd = kvm_open( NULL, NULL, NULL, O_RDONLY, NULL ) ) == NULL )
{
perror( "kvm_open" );
return( -1 );
}
/*
* 遍历P区
*/
while ( ( cur_proc = kvm_nextproc( kd ) ) )
{
/*
* 注意理解这里为什么要使用kvm_kread()函数,否则很容易出现段故障
*/
#if SOLARIS == 7
if ( kvm_kread( kd, ( uintptr_t )cur_proc->p_pidp, &p, sizeof( p ) )< 0 )
#elif SOLARIS == 6
if ( kvm_kread( kd, ( unsigned long )cur_proc->p_pidp, ( char * )&p,sizeof( p ) ) < 0 )
#endif
{
perror( "kvm_kread" );
continue;
}
pid = p.pid_id;
if ( ( cur_user = kvm_getu( kd, cur_proc ) ) != NULL )
{
/* fprintf( stderr, "cur_proc = %p cur_user = %p\n", cur_proc, cur_user );*/
error = kvm_getcmd( kd, cur_proc, cur_user, &argv, NULL );
/*
* fprintf( stderr, "[ %s ] is: <%u>\n", cur_user->u_comm, (unsigned int )pid );
*
* 比如in.telnetd、syslogd、bash、login
*/
if ( error == -1 )
{
/*
* 失败,比如argv[]已经被进程自己修改过
*/
if ( cur_user->u_comm[0] != '\0' )
{
/*
* 从另外一个地方获取信息
*/
p_name = cur_user->u_comm;
}
}
/*
* 成功
*/
else
{
/*
* fprintf( stderr, "[ %s ] is: <%u>\n", argv[0], ( unsigned int)pid );
*
* 比如-bash、login、in.telnetd、/usr/sbin/syslogd
*/
p_name = argv[0];
}
}
if ( p_name )
{
if ( ( strcmp( p_name, name ) == 0 ) || step( p_name, expbuf ) )
{
/*
* -1做为无效pid对待
*/
if ( skipit != -1 && pid == skipit )
{
pid = -1;
}
/*
* 找到匹配,返回pid
*/
else
{
/*
* 跳出while循环
*/
break;
}
}
}
if ( argv != NULL )
{
/*
* argv_free( argv );
*/
free( argv );
argv = NULL;
}
/*
* 必须增加这条,否则流程有问题
*/
p_name = NULL;
} /* end of while */
if ( argv != NULL )
{
/*
* 根据kvm_getu(3K)手册页的描述,我企图释放指针数组的各个元素以及
* 指针数组本身。测试下来,只能释放指针数组本身,无法单独释放各个
* 元素,否则出现总线错误。个人认为kvm_getu(3K)手册页的描述是正确
* 的,有待进一步测试
*/
/*
* argv_free( argv );
*/
free( argv );
argv = NULL;
}
kvm_close( kd );
return( pid );
} /* end of getpidbyname */

static void usage ( char * arg )
{
fprintf( stderr, " Usage: %s <proc_name>\n", arg );
exit( EXIT_FAILURE );
} /* end of usage */

int main ( int argc, char * argv[] )
{
pid_t pid;

if ( argc != 2 )
{
usage( argv[0] );
}
pid = getpidbyname( argv[1], -1 );
if ( pid != -1 )
{
fprintf( stderr, "[ %s ] is: <%u>\n", argv[1], ( unsigned int )pid );
return( EXIT_SUCCESS );
}
return( EXIT_FAILURE );
} /* end of main */
--------------------------------------------------------------------------
fallinleave 2006-05-23
  • 打赏
  • 举报
回复
第一种办法是读取/proc接口提供的信息

--------------------------------------------------------------------------
/*
* gcc -Wall -pipe -O3 -o getpid getpid.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/procfs.h>
#include <unistd.h>
#include <stropts.h>
#include <dirent.h>
#include <fcntl.h>

static pid_t getpidbyname ( char * name, pid_t skipit )
{
DIR * dirHandle; /* 目录句柄 */
struct dirent * dirEntry; /* 单个目录项 */
prpsinfo_t prp;
int fd;
pid_t pid = -1;

if ( ( dirHandle = opendir( "/proc" ) ) == NULL )
{
return( -1 );
}
/*
* 下面使用相对路径打开文件,所以必须进入/proc
*/
chdir( "/proc" );
while ( ( dirEntry = readdir( dirHandle ) ) != NULL )
{
if ( dirEntry->d_name[0] != '.' )
{
/*
* fprintf( stderr, "%s\n", dirEntry->d_name );
*/
if ( ( fd = open( dirEntry->d_name, O_RDONLY ) ) != -1 )
{
if ( ioctl( fd, PIOCPSINFO, &prp ) != -1 )
{
/*
* fprintf( stderr, "%s\n", prp.pr_fname );
*/
/*
* 这里是相对路径,而且不带参数
*/
if ( !strcmp( prp.pr_fname, name ) )
{
pid = ( pid_t )atoi( dirEntry->d_name );
/*
* -1做为无效pid对待
*/
if ( skipit != -1 && pid == skipit )
{
pid = -1;
}
else
{
/*
* 找到匹配
*/
close( fd );
/*
* 跳出while循环
*/
break;
}
}
}
close( fd );
}
}
} /* end of while */
closedir( dirHandle );
return( pid );
} /* end of getpidbyname */

static void usage ( char * arg )
{
fprintf( stderr, " Usage: %s <proc_name>\n", arg );
exit( EXIT_FAILURE );
} /* end of usage */

int main ( int argc, char * argv[] )
{
pid_t pid;

if ( argc != 2 )
{
usage( argv[0] );
}
pid = getpidbyname( argv[1], -1 );
if ( pid != -1 )
{
fprintf( stderr, "[ %s ] is: <%u>\n", argv[1], ( unsigned int )pid );
return( EXIT_SUCCESS );
}
return( EXIT_FAILURE );
} /* end of main */
--------------------------------------------------------------------------
yingge 2006-05-23
  • 打赏
  • 举报
回复
这样就先写一个shell,查询进程是否存在,存在返回1,不存在返回0。
在查询程序里执行shell得到返回值就可以了。
zez 2006-05-23
  • 打赏
  • 举报
回复
1.ps
2.查询/proc

不要告诉我你不知道 proc 是什么.. 不知道赶紧去 man
BaiYangSpirit 2006-05-23
  • 打赏
  • 举报
回复
ps -ef | grep '进程名' > ./process

然后用程序读取process这个文件
xuzhike 2006-05-23
  • 打赏
  • 举报
回复
To:lzf_china(岁月如歌)
请问怎么写可以实现?
kill需要pid,或者给所有进程都发该信号,如果被查询进程对该信号不进行处理,那我怎么知道它是否存在?
激荡数十年 2006-05-23
  • 打赏
  • 举报
回复
可以使用kill()函数
xuzhike 2006-05-23
  • 打赏
  • 举报
回复
To:yingge(盼胖)
这是客户的要求,查询程序还要做一系列的事情,查询某个进程只是为了决定是否继续做下去;而且
查询进程与被查询进程有进程间通信的。
假如被查询进程不存在,则查询进程终止命令;如果存在,则会把很多消息放进共享queue中,供被查询进程使用的
yingge 2006-05-23
  • 打赏
  • 举报
回复
有必要用C吗?用shell多好
xuzhike 2006-05-23
  • 打赏
  • 举报
回复
对于我要查询的进程,只知道它的名字,其他一无所知;而且查询进程和被查询的进程毫无瓜葛,所以
fallinleave(飞翔) :
你说的那些函数,我察看了《linux下C函数》一遍,没有相关的,不过只有一个函数system(char*)比较接近,用来执行shell的,不过返回值是该shell命令是否执行成功的结果;当然,可以做个变体,比如,写文件,然后读文件检查。但这个时候都是有延迟的---I/O操作比较花费时间
我个人觉得,执行shell来检查,延迟应该比较大

有没有更好的方法呢
fallinleave 2006-05-23
  • 打赏
  • 举报
回复
我觉得应该不难,你参考一本《linux编程》的书就行,ps命令不就有这个功能嘛。
我记得不错的话应该有getuid...等一系列函数。
jixingzhong 2006-05-23
  • 打赏
  • 举报
回复
查询运行进程信息 ...

69,375

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧