免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2328 | 回复: 8
打印 上一主题 下一主题

信号-错在哪里? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-10-24 15:45 |只看该作者 |倒序浏览
目的:
用系统调用signal()让父进程捕捉键盘上来的中断信号(按Ctrl-C键);当捕捉到中断信号后,父进程用系统调用kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:
 Child Process 1 is Killed by Parent!
 Child Process 2 is Killed by Parent!
 父进程等待两个子进程终止后,输出如下的信息后终止:
 Parent Process is Killed!

程序:
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
void sigproc(int);
void sigcld1(int);
void sigcld2(int);

int main(int argc, char **argv)
{
        pid_t pid1,pid2;
        int status1,status2;
        if(signal(SIGINT,&sigproc)==SIG_ERR)
        {
                printf("signal error!\n");
                exit(0);
        }
        if((pid1=fork())<0)
        {
                printf("fork 1 error!\n");
                exit(0);
        }
        else if(pid1==0)
        {
                if(signal(SIGUSR1,&sigcld1)==SIG_ERR)
                {
                        printf("child 1 sig error!\n");
                        exit(-1);
                }
                pause();
                _exit(0);
        }

        if((pid2=fork())<0)
        {
                printf("fork 1 error!\n");
                exit(0);
        }
        else if(pid2==0)
        {
                if(signal(SIGUSR1,&sigcld2)==SIG_ERR)
                {
                        printf("child 2 sig error!\n");
                        exit(-1);
                }
                pause();
                _exit(0);
        }
        waitpid(pid1,&status1,WUNTRACED);
        waitpid(pid2,&status2,WUNTRACED);       
        pause();
        kill(pid1,SIGUSR1);
        kill(pid2,SIGUSR1);
        exit(0);
}

void sigproc(int signo)
{
        if(signo==SIGINT)
        {
                printf("Parent Process is Killed\n");
        }
        return;
}
void sigcld1(int signo)
{
        if(signo==SIGUSR1)
        {
                printf("Child Process 1 is Killed By Parent\n");
        }
        return;
}
void sigcld2(int signo)
{
        if(signo==SIGUSR1)
        {
                printf("Child Process 1 is Killed By Parent\n");
        }
        return;
}

现象:按ctrl+C时输出:
Parent Process is Killed
Parent Process is Killed
Parent Process is Killed
再按CTRL+C时输出:
Parent Process is Killed
程序停止。

请问:为什么输出三次Parent Process is Killed?父进程没有向子进程发送kill信号?

请各位高手赐教。

论坛徽章:
0
2 [报告]
发表于 2006-10-24 16:11 |只看该作者
初始状态:
父进程停在第一个waitpid处。子进程停在pause处。
发送第一个信号
2个子进程子进程打印信息,然后退出
父进程打印信息,并收到了两个子进程的退出状态,停在pause处。
发送第二次信号
因为信号处理函数没有再说明处理,按默认方式,父进程退出

论坛徽章:
0
3 [报告]
发表于 2006-10-24 16:18 |只看该作者

回复 1楼 hebioldman 的帖子

#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
void sigproc(int);
void sigcld1(int);
void sigcld2(int);

int main(int argc, char **argv)
{
        pid_t pid1,pid2;
        int status1,status2;
        if(signal(SIGINT,&sigproc)==SIG_ERR)
        {
                printf("signal error!\n");
                exit(0);
        }
        if((pid1=fork())<0)
        {
                printf("fork 1 error!\n");
                exit(0);
        }
        else if(pid1==0)
        {
                if(signal(SIGUSR1,&sigcld1)==SIG_ERR)
                {
                        printf("child 1 sig error!\n");
                        exit(-1);
                }
                signal(SIGINT, SIGDFL); //add this
                pause();
                _exit(0);
        }

        if((pid2=fork())<0)
        {
                printf("fork 1 error!\n");
                exit(0);
        }
        else if(pid2==0)
        {
                if(signal(SIGUSR1,&sigcld2)==SIG_ERR)
                {
                        printf("child 2 sig error!\n");
                        exit(-1);
                }
                signal(SIGINT, SIG_DFL); //add this
                pause();
                _exit(0);
        }
        waitpid(pid1,&status1,WUNTRACED);
        waitpid(pid2,&status2,WUNTRACED);      
        pause();
        kill(pid1,SIGUSR1); //no use
        kill(pid2,SIGUSR1); //no use
        exit(0);
}

void sigproc(int signo)
{
        if(signo==SIGINT)
        {
                printf("Parent Process is Killed\n");
        }
        return;
}
void sigcld1(int signo)
{
        if(signo==SIGUSR1)
        {
                printf("Child Process 1 is Killed By Parent\n");
        }
        return;
}
void sigcld2(int signo)
{
        if(signo==SIGUSR1)
        {
                printf("Child Process 1 is Killed By Parent\n");
        }
        return;
}

论坛徽章:
0
4 [报告]
发表于 2006-10-24 16:34 |只看该作者

回复 3楼 chzht001 的帖子

谢谢回复。
不过,添加的两个signal是告知子进程采用系统默认方式处理SIGINT信号,事实上,SIGINT信号被父进程捕获,而父进程并没有将它传递给子进程。所以输出和原来一样。
我的疑问是:
  1)如何让父进程在信号处理函数中给子进程发送kill信号?
  2)pause后主进程没用继续往下执行?
一开始我在sigproc函数中采用:kill(-1,SIGUSR1);直接导致一些系统进程退出。进入未登录状态。
也就是说,没有满足一开始的目的。

论坛徽章:
0
5 [报告]
发表于 2006-10-24 17:01 |只看该作者

回复 4楼 hebioldman 的帖子

你已
waitpid(pid1,&status1,WUNTRACED);
waitpid(pid2,&status2,WUNTRACED);  

kill(pid1,SIGUSR1); //no use
kill(pid2,SIGUSR1); //no use
简直不能想象啊!!!
waitpid什么意思知道不?

论坛徽章:
0
6 [报告]
发表于 2006-10-24 17:19 |只看该作者

回复 5楼 chzht001 的帖子

waitpid是等待子进程退出返回。
事实上把waitpid放在kill之后才对。
问题就是出在这里。
呵呵,修改了一下,ok了。
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
void sigproc(int);
void sigcld1(int);
void sigcld2(int);

int main(int argc, char **argv)
{
        pid_t pid1,pid2;
        int status1,status2;
        if(signal(SIGINT,&sigproc)==SIG_ERR)
        {
                printf("signal error!\n");
                exit(0);
        }
        if((pid1=fork())<0)
        {
                printf("fork 1 error!\n");
                exit(0);
        }
        else if(pid1==0)
        {
                if(signal(SIGUSR1,&sigcld1)==SIG_ERR)
                {
                        printf("child 1 sig error!\n");
                        exit(-1);
                }
                pause();
                _exit(0);
        }

        if((pid2=fork())<0)
        {
                printf("fork 1 error!\n");
                exit(0);
        }
        else if(pid2==0)
        {
                if(signal(SIGUSR1,&sigcld2)==SIG_ERR)
                {
                        printf("child 2 sig error!\n");
                        exit(-1);
                }
                pause();
                _exit(0);
        }  
        pause();
        kill(pid1,SIGUSR1);
        kill(pid2,SIGUSR1);
        waitpid(pid1,&status1,WUNTRACED);
        waitpid(pid2,&status2,WUNTRACED);  
        printf("Parent killed by SIGINT.\n");
        exit(0);
}

void sigproc(int signo)
{
        if(signo==SIGINT)
        {
                printf("Parent get SIGINT.\n");
        }
        return;
}

void sigcld1(int signo)
{
        if(signo==SIGUSR1)
        {
                printf("Child Process 1 is Killed By Parent\n");
        }
        return;
}
void sigcld2(int signo)
{
        if(signo==SIGUSR1)
        {
                printf("Child Process 1 is Killed By Parent\n");
        }
        return;
}

论坛徽章:
0
7 [报告]
发表于 2010-03-07 10:06 |只看该作者
楼主的代码问题太多了,子进程继承父进程的信号处理函数,其次没有考虑父子进程的执行顺序

论坛徽章:
0
8 [报告]
发表于 2010-03-07 22:10 |只看该作者
这段代码"  waitpid(pid1,&status1,WUNTRACED);
        waitpid(pid2,&status2,WUNTRACED);”
子进程都结束了还怎么接受  kill(pid1,SIGUSR1);
        kill(pid2,SIGUSR1);
这两个信号啊!
输出三个Parent Process is Killed
Parent Process is Killed
Parent Process is Killed是因为子进程继承父进程的正文区

论坛徽章:
0
9 [报告]
发表于 2010-03-07 22:13 |只看该作者
子进程继承了父过程的SIGUSR1信号处理函数,当然会有三次啊。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP