1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <sys/types.h>
4 #include <signal.h>
5 #include <unistd.h>
6
7 .......
55 return 0;
56 }
57
这里代码不够完美,删掉了
后面有比较好的,可用的代码
有兴趣的请自行取阅
最终解决问题请见16楼和17楼
[url=http://bbs.chinaunix.net/viewthread.php?tid=907131&pid=6524793&page=2&extra=page%3D1#pid6524793]http://bbs.chinaunix.net/viewthread.php?tid=907131&pid=6524793&page=2&extra=page%3D1#pid6524793
[ 本帖最后由 net_robber 于 2007-3-13 20:17 编辑 ]
新手上路2世 回复于:2007-03-09 14:11:05
楼主的钻研精神令人敬佩!!! 继续关注
net_robber 回复于:2007-03-09 14:14:47
谢谢
isnowran 回复于:2007-03-09 14:42:29
二位的观点可能有点误区
1。杀掉父进程,子进程并不会被杀掉
引用:
考虑两个问题
1、自进程已经被干掉了,但是楼主没有waitpid(),所以还以为子进程还再。我见过有人这样
2、杀掉父进程,子进程不就被干掉了么????
2。子进程会继承父进程的信号屏蔽
引用:
不是这样的! 子进程是不会继承父进程的信号设置的, 所以只是在父进程给ignore掉了!! 子进程还是会收到信号的!!
你可以试试上面那个程序就知道了!!
net_robber 回复于:2007-03-09 14:49:33
谢谢楼上回复
现在这个问题没有彻底解决,还剩下一个关键问题
进程A 用kill( 0, SIG )
自杀后,
为什么它的父进程也被干掉了???
isnowran 回复于:2007-03-09 15:06:29
kill 0的意义是发送信号给它的进程组中所有进程,父进程若也在同样的进程组,当然也会接收到信号了
net_robber 回复于:2007-03-09 15:15:57
但是为什么另外一个拥有同样PID的后台进程不被干掉
为什么拥有同样进程的BASH进程没有被干掉?????
这和Man里面解释的不一样啊
net_robber 回复于:2007-03-09 15:20:17
如果现在我只想杀掉进程,以及他的全部子进程
我改怎么做??
每个进程在退出之前杀掉自己的子进程这种方法 不算
net_robber 回复于:2007-03-09 15:31:12
可能只有利用SHELL比较快了
net_robber 回复于:2007-03-09 15:32:57
ps awx -o "%p %P"|grep -w PID| awk '{ print $1 }'|xargs kill -9
isnowran 回复于:2007-03-09 15:41:13
把你的程序简单修改了一下
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
void fun_kill( int sig )
{
kill ( 0, SIGKILL );
}
int main( void )
{
for( int i = 0; i < 3; i++ )
{
if( 0 == fork() )
{
break;
}
}
if( getpid() == getpgid( 0 ) )
{
signal ( SIGTERM, SIG_IGN );
sleep( 3 );
kill( 0, SIGTERM );
}
else
{
while ( 1 )
{
printf ( "pid:%d ppid:%d\n", getpid(), getppid() );
sleep ( 1 );
}
}
printf( "game over\n" );
return 0;
}
isnowran 回复于:2007-03-09 15:46:16
引用:原帖由 net_robber 于 2007-3-9 15:15 发表
但是为什么另外一个拥有同样PID的后台进程不被干掉
为什么拥有同样进程的BASH进程没有被干掉?????
这和Man里面解释的不一样啊
不太明白你说的"同样pid的后台进程"是什么意思,也不明白"拥有同样进程的BASH进程"是什么意思,请解释一下:)
l新的进程在shell环境生成后,一般都有setsid的操作,这样它们就不在同一个会话期,当然也不在同一个进程组了,所以shell不会受到kill 0的影响
net_robber 回复于:2007-03-09 18:07:45
引用:原帖由 isnowran 于 2007-3-9 15:46 发表
不太明白你说的"同样pid的后台进程"是什么意思,也不明白"拥有同样进程的BASH进程"是什么意思,请解释一下:)
l新的进程在shell环境生成后,一般都有setsid的操作,这样它们就不在同一 ...
大概就是你说的原因
还没有研究这么深入。
net_robber 回复于:2007-03-09 18:13:22
getpid(), getppid()以前没有用过,学习一下再来讨论
net_robber 回复于:2007-03-09 18:43:51
最终提供两套代码:
一套通过gid控制;
另一讨使用SHELL工作。
net_robber 回复于:2007-03-09 18:45:01
这是通过gid控制
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
void fun(int sig)
{
kill(0 , SIGKILL );
}
int main( void )
{
int pid = 0;
if( pid = fork() )
{
fflush( stdout );
sleep ( 5 );
printf ( "kill ( pid, SIG ); \n");
fflush( stdout );
kill ( pid, SIGUSR1 );
sleep ( 10 );
printf ( "the father is still alive!\n", pid );
fflush( stdout );
}
else
{
setpgid(0,0); //line 30
signal( SIGUSR1, fun );
if( pid = fork() )
{
int i = 10;
while ( i-- )
{
fflush( stdout );
sleep ( 1 );
}
}
else
{
int i = 10;
while ( i-- )
{
printf ( "in grandsun , pid= %d\nin grandsun , ppid= %d\n", getpid(), getppid() );
fflush( stdout );
sleep ( 1 );
}
}
}
return 0;
}
[ 本帖最后由 net_robber 于 2007-3-13 10:04 编辑 ]
net_robber 回复于:2007-03-09 18:46:35
这是通过SHELL工作
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
void fun_kill( int sig )
{
printf( "process with PID %d got a signal!\n", getpid() );
fflush( stdout );
char *pre = "ps awx -o \"\%p \%P\"|grep -w ";
char *post = " | awk \'{ print $1 }\'|xargs kill -9";
char *command = malloc( 1024*sizeof (char) );
char *c_pid = malloc( 8*sizeof (char) );
memset ( command, 0, 1024*sizeof(char) );
memset ( c_pid, 0, 8*sizeof(char) );
char *a,*b;
char c;
//get PID string * NOTE: here the string is in a wrong order
int len = 0;
int tmp = getpid();
for ( len = 0; tmp; tmp /= 10 )
{
*( c_pid + len ) = (tmp%10)+'0';
len++;
}
printf ( "%s has %d char\n", c_pid,len );
fflush( stdout );
// deal the order
a = c_pid;
b = c_pid+len-1;
printf ("c_pid = %d\n",c_pid);
printf ("a = %d\n",a);
printf ("b = %d\n",b);
fflush( stdout );
while ( a < b )
{
c = *a;
*a =*b;
*b = c;
a += sizeof(char);
b -= sizeof(char);
}
/*
int i = 0;
while ( i<len )
{
printf ("%c", *(c_pid+i) );
}
*/
printf ( "command1:%s\n", command );
fflush( stdout );
strcat ( command, pre );
strcat ( command, c_pid );
strcat ( command, post );
printf ( "command2:%s\n", command );
fflush( stdout );
system( command );
}
int main( void )
{
int pid = 0;
if( pid = fork() )
{
// printf ( "in father, pid= %d\nin father, child pid = %d\n", getpid(), pid );
fflush( stdout );
sleep ( 5 );
printf ( "kill ( pid, SIG ); \n");
fflush( stdout );
kill ( pid, SIGUSR1 );
sleep ( 10 );
printf ( "the father is still alive!\n", pid );
fflush( stdout );
}
else
{
signal ( SIGUSR1, fun_kill );
if( pid = fork() )
{
int i = 10;
while ( i-- )
{
// printf ( "in child, pid= %d\nin child, ppid= %d\n", getpid(), getppid() );
fflush( stdout );
sleep ( 1 );
}
}
else
{
int i = 10;
while ( i-- )
{
// printf ( "in grandsun , pid= %d\nin grandsun , ppid= %d\n", getpid(), getppid() );
fflush( stdout );
sleep ( 1 );
}
}
}
return 0;
}
[ 本帖最后由 net_robber 于 2007-3-13 10:07 编辑 ]
net_robber 回复于:2007-03-12 09:58:44
关于使用PGID的方法
请注意代码的第30行
这里需要说明:
setpgid函数后,本进程不再使用父进程的gid
其后,本进程产生的子进程使用本进程setpgid以后的gid
因此可以做到 SIGKILL后杀死本进程及本进程的所有子进程
isnowran 回复于:2007-03-12 10:26:34
2个问题
1。生成进程后马上杀掉进程,这么做好像没什么意义,毕竟搂长的初衷是怎么杀掉所有子进程,此时应该父进程应该是已经生成一堆进程后并且没有保存子进程pid的情况
2。既然是指定pid单独发送信号,子进程再设置为组长好像没什么意义
net_robber 回复于:2007-03-12 10:34:15
前几天,有个兄弟踢出了一个要杀掉所有子进程的问题
我当时作出了一些回答,但是并没有帮他完全解决问题。
所以,这里,我尝试把这个问题彻底解决
上面的代码只是一个DEMO。
谢谢关注,呵呵
只是不知道,当初提出这个问题的那位 兄弟(沙发),有没有看到这个帖子。
如果看到了,希望告知,我得方法能不能帮你解决问题
告化甲头 回复于:2007-03-12 12:03:47
引用:原帖由 net_robber 于 2007-3-12 10:34 发表
前几天,有个兄弟踢出了一个要杀掉所有子进程的问题
我当时作出了一些回答,但是并没有帮他完全解决问题。
所以,这里,我尝试把这个问题彻底解决
上面的代码只是一个DEMO。
谢谢关注,呵呵
只是 ...
isnowran提出的问题你还是没有解决嘛,并且,这个确实不能算是"杀死所有子进程"的方法
[ 本帖最后由 告化甲头 于 2007-3-12 12:06 编辑 ]
net_robber 回复于:2007-03-12 13:23:20
?
不知道我是不是没有看懂你的意思
这里,我的两种方法都已经做到了杀掉全部子进程
请问你的意思是???
告化甲头 回复于:2007-03-12 14:36:16
正常情况下,不可能如你所假设那样,生成子进程后马上就杀掉,这样没什么实际意义,大部分情况是,生成若干进程,工作一段时间后,父进程接收到要停止子进程的指令后才开始终止子进程的,比如
for(int i=0; i<3; i++)
{
父进程生成子进程
if(子进程)
循环执行工作
}
父进程等待指令
试问在这种情况下,父进程怎么才能把上面生成的3个或N个子进程结束呢?
net_robber 回复于:2007-03-12 14:58:21
父进程执行kill(0,SIGKILL)
前提需要父进程执行setpgid(,)
man 2 kill
net_robber 回复于:2007-03-12 15:00:13
而且我说过了,上面只是一个DEMO
你当然可以在你需要的时候在执行杀掉子进程
在上面的DEMO中
等待执行kill的方法是等待信号SIGUSR1
net_robber 回复于:2007-03-12 15:01:27
你不明白什么是DEMO么???
net_robber 回复于:2007-03-12 15:05:47
任何问题的解决,都是有前提环境的假设的
你的问题已经改变了我的假设
如果回答你的问题就像回答“如何让一个死人学会放屁”一样,有点麻烦
告化甲头 回复于:2007-03-12 15:27:21
哦,fork了2次,没看清楚,歹势
converse 回复于:2007-03-12 22:52:08
好帖保留了。
但是几位以后帖代码的时候注意不要把行号给加进来了,不然别人copy编译会比较麻烦。
net_robber 回复于:2007-03-13 10:08:13
已经修改了
去掉了行号
以后会注意的
ttphc 回复于:2007-03-13 12:31:15
seem good
|