关于kill()系统调用的一个问题

zhe_wang_2012 2011-10-04 03:17:33
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>

void send_signal(int pid,int signal)
{
if(kill(pid,signal) == 0)
printf("send signal success.\n");
else
printf("send signal failed.\n");
}


void received_signal(int signal)
{
if(signal == SIGUSR1)
printf("22222222222222222\n");
}

void handler(int signal)
{
if (signal == SIGUSR1) {
printf("11111111111111111111111\n");
}
}

int main()
{
pid_t pid;
int status = 0;
int rc;

if((pid = fork()) == 0) {
signal(SIGUSR1,received_signal);
printf("i am child process pid = %d.\n",getpid());
while (1);
}

if ((pid = fork()) == 0) {
signal(SIGUSR1,handler);
printf("the second process pid = %d\n",getpid());
while (1);
}

sleep(1);
printf("pid = %d\n",(pid_t)pid);
rc = kill(0,SIGUSR1);
printf("rc = %d\n",rc);
printf("333333333333333333333333333333\n");
printf("i am parent process.pid = %d\n",getpid());
wait(&status);
exit(0);
}

这是我写的一个小的测试程序,想通过kill向进程组发送信号。
问题是:把kill的确把信号发送到所在的进程组了,可在执行
kill函数时好像就阻塞了,下面的很多代码就不执行了,求解!
...全文
294 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhe_wang_2012 2011-10-05
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 qq120848369 的回复:]

还是让我自己测试了,一切如我所说,你最好把子进程的代码改一下,免得弄俩死在while上的僵尸进程,连init都拿它们俩没办法。

C/C++ code
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait……
[/Quote]
我想问下,这个实现多个进程之间的信号通信之间还有同步的问题就是。
必须是先执行信号的注册就是signal(),然后才是发送信号,对不?
一般这样的同步不是用信号量的PV操作来实现的么,怎么用管道,是不是有点
太小题大作了。
qq120848369 2011-10-04
  • 打赏
  • 举报
回复
还是让我自己测试了,一切如我所说,你最好把子进程的代码改一下,免得弄俩死在while上的僵尸进程,连init都拿它们俩没办法。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>

void send_signal(int pid,int signal)
{
if(kill(pid,signal) == 0)
printf("send signal success.\n");
else
printf("send signal failed.\n");
}


void received_signal(int signal)
{
if(signal == SIGUSR1)
printf("22222222222222222\n");
}

void handler(int signal)
{
if (signal == SIGUSR1) {
printf("11111111111111111111111\n");
}
}

int main()
{
pid_t pid;
int status = 0;
int rc;

if((pid = fork()) == 0) {
signal(SIGUSR1,received_signal);
printf("i am child process pid = %d.\n",getpid());
pause();
exit(0);
}

if ((pid = fork()) == 0) {
signal(SIGUSR1,handler);
printf("the second process pid = %d\n",getpid());
pause();
exit(0);
}

sleep(1);
printf("pid = %d\n",(pid_t)pid);
rc = kill(0,SIGUSR1);
printf("rc = %d\n",rc);
printf("333333333333333333333333333333\n");
printf("i am parent process.pid = %d\n",getpid());
wait(&status);
exit(0);
}


运行结果:

linux-6v95:/home/owenliang/csdn/cAndCpp # main
the second process pid = 6565
i am child process pid = 6564.
pid = 6565
用户定义信号 1
linux-6v95:/home/owenliang/csdn/cAndCpp # 11111111111111111111111
22222222222222222

别看下边的1111,2222的,那只是父进程这个前台进程Kill返回前退出了,shell打印命令行,两个子进程受到信号以后打出来的信息,你输个clear就清掉了,现在已经回到shell了。

父进程从:用户定义信号 1 那里就退出了,正是kill返回前退出的。

另外,程序如果要严谨的话,有两点:

1,我改的地方,子进程pasue();被信号中断返回后exit(),免得继续跑下边的代码段,弄的子子孙孙一场乱伦。 当然,你的代码也不会出现这种乱伦问题,但while(1)死在那里一是CPU占用率大,二是父进程退出后,Init接受孤儿进程,但孤儿进程不exit,于是成了僵尸。

2,父子进程你简单的用sleep同步,我只是建议严谨的用管道做同步,两个子进程给管道各写1字节,父进程阻塞读2字节后调用kill,管道和FIFO在阻塞模式下,1,2个字节都小于PIPE_BUF,属于原子写,阻塞到全能写入才返回,所以木有问题。
zhe_wang_2012 2011-10-04
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 qq120848369 的回复:]

If pid is 0, sig shall be sent to all processes (excluding an unspecified set of system processes) whose process group ID is equal
to the process group ID of the sender, and for which the pro……
[/Quote]

哦,终于明白了,没有考虑父进程给自己也发送了SIGUSR1这个信号,查了下SIGUSR1这个信号的默认的
处理是将进程终止,难怪怎么说后面的都不执行了。至于while(1); 和while(1)pause();这不是主要的
原因,前面一个耗系统资源,后面一种写法不耗系统资源。

谢谢了!
qq120848369 2011-10-04
  • 打赏
  • 举报
回复
SIGUSR1和SIGUSR2
描述 用户定义的信号
默认动作 进程异常终止
SA_SIGINFO宏


帮你查到了,如果你的代码情况是子进程正常打印,父进程kill没返回就退出了,那就一切可以解释了。
qq120848369 2011-10-04
  • 打赏
  • 举报
回复
If pid is 0, sig shall be sent to all processes (excluding an unspecified set of system processes) whose process group ID is equal
to the process group ID of the sender, and for which the process has permission to send a signal.


if the value of pid causes sig to be generated for the sending process, and if sig is not blocked for the calling thread and if no
other thread has sig unblocked or is waiting in a sigwait() function for sig, either sig or at least one pending unblocked signal
shall be delivered to the sending thread before kill() returns.


意思就是你给父进程同组发送信号,同样也会发给父进程自己,在kill返回之前这个信号被处理,而父进程没有注册SIGUSR1,你可以查一下SIGUSR1默认的处理是什么。

两个子进程和父进程都是同组的,接受到信号后按道理是会打印的啊。

把while(1)换成while(1){pause();}看看。
zhe_wang_2012 2011-10-04
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 dengxiayehu 的回复:]

不好意思,搞错了,最近Android搞得比较多……
刚man了下kill,原型:
C/C++ code

int kill(pid_t pid, int sig);


对于pid = 0的情况,信号sig会发送给调用进程所在的进程组中的每个进程。
所以,也就是说,父进程及其所创建的子进程统统被杀掉了。
[/Quote]

不明白给进程组发送信号,怎么就给这个进程组的所有进程都杀死了?求解释?
zhe_wang_2012 2011-10-04
  • 打赏
  • 举报
回复
int kill(pid_t pid, int sig);


The kill() system call can be used to send any signal to any process group or process.

If pid is positive, then signal sig is sent to the process with the ID specified by pid.

If pid equals 0, then sig is sent to every process in the process group of the calling process.

If pid equals -1, then sig is sent to every process for which the calling process has permission to send signals, except for process 1 (init), but
see below.

If pid is less than -1, then sig is sent to every process in the process group whose ID is -pid.

kill(0, SIGUSR1);不是给进程组发送信号么?怎么扯到把父进程杀死了?

_了凡_ 2011-10-04
  • 打赏
  • 举报
回复
不好意思,搞错了,最近Android搞得比较多……
刚man了下kill,原型:

int kill(pid_t pid, int sig);

对于pid = 0的情况,信号sig会发送给调用进程所在的进程组中的每个进程。
所以,也就是说,父进程及其所创建的子进程统统被杀掉了。
_了凡_ 2011-10-04
  • 打赏
  • 举报
回复
fork()这个函数会返回2次,若返回大于0的任何数时它代表的是子进程的进程号;
若返回0,则表示父进程的进程号(也就是当前进程),而你

rc = kill(0, SIGUSR1);

这个kill函数却要杀死进程号为0进程,这不扯了,把自己(父进程)给杀掉了,
所以当然后面没有输出了。

23,216

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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