linux 系统信号忽略和system函数返回值问题(system的实现)
signal(SIGHUP, SIG_IGN);
signal信号函数,第一个参数表示需要处理的信号值(SIGHUP),第二个参数为处理函数或者是一个表示,这里,SIG_IGN表示忽略SIGHUP那个注册的信号。
SIGHUP和控制台操作有关,当控制台被关闭时系统会向拥有控制台sessionID的所有进程发送HUP信号,默认HUP信号的action是 exit,如果远程登陆启动某个服务进程并在程序运行时关闭连接的话会导致服务进程退出,所以一般服务进程都会用nohup工具启动或写成一个 daemon。
#######################################################################################################
system函数返回值问题(system的实现)—signal(SIGCHLD,SIG_DFL);ret=system("command");signal(SIGNCHLD,SIG_IGN);
2011-03-19 17:33:53| 分类: Linux系统编程|字号 订阅
1、关于在system中获取子进程的返回值与SIGCHLD
在Linux我们一般写的是Server程序,所以,一般在main函数中,首先将进程转换为后台进程,即调用deamon,deamon的一般实现,参见::
http://blog.163.com/xychenbaihu@yeah/blog/static/132229655201121611452549/
deamon的实现中会忽略下面的信号:
signal(SIGINT, SIG_IGN); //当在终端上按下ctrl+c后,会产生SIGINT信号。
signal(SIGHUP, SIG_IGN); //终端退出时,会给所有的进程发送SIGHUP信号。
signal(SIGQUIT, SIG_IGN); //终端退出时,会给所有的进程发送SIGQUIT信号。
signal(SIGPIPE, SIG_IGN); //往没有读进程的管道中进行写操作。
signal(SIGTTOU, SIG_IGN); //后台进程写tty
signal(SIGTTIN, SIG_IGN); //后台进程读tty
signal(SIGCHLD, SIG_IGN); /*子进程先于父进程结束时,会给父进程发送SIGCHLD信号如果
1、父进程没有忽略SGICHLD信号;
或者
2、父进程没有调用wait或waitpid函数。
那么子进程将僵死。 ( 在2.6内核,只要父进程显式忽略了SIGCHLD信号, 那么子进程将不会僵死,那么system将得不到子进程的退出状态。 也就是说system函数的返回值并不是子进程退出时的状态。 而2.4内核,只要父进程没有调用wait系列函数,子进程就将僵死。 不论是否忽略了SIGCHLD信号。 )
*/
signal(SIGTERM, SIG_IGN); /*
当kill pid时,向进程发送SIGTERM信号。
SIGTERM信号的默认处理是进程退出。
SIGTERM是进程在有可能的情况下退出。
注意::
killall -9 process_name
发送的SIGKILL信号,强制进程退出。
*/
如果,我们在我们的server中需要调用system来调用外部脚本或程序来执行某写工作。
例如:
在脚本中通过wget下载文件::
#!/bin/bash
FILENAME=$0
PATHNAME=$1
wget $FILENAME $PATHNAME
if [ $? -eq 0 ] ; then
exit 0
else
exit -1
fi
例如::
char command[1024];
url=http://test/test.rar;
pathname="./data";
sprintf(command,"./download.sh %s %s",url,pathname);
int ret = system(command);
if( ret == 0)
{
//成功
}
else
{
//失败
}
注意::
其中ret用来接收子进程退出是的返回值。即exit的返回值。
但是由于在deamon中忽略了SIGCHLD信号,所以主进程将不再接收子进程的返回值。所以,ret的值不能正确反映子进程的退出状态。
正确的做法是::
signal(SIGCHLD,SIG_DFL); //默认处理方式,是接收子进程的返回值。
system(command);
signal(SIGCHLD,SIG_IGN);
2、system相关问题::
system函数其实是调用fork,exec,waitpid来实现的。
1、fork一个进程;
2、在子进程中调用exec去执行新程序。
3、在父进程中调用waitpid去等待子进程结束。
如果在父进程已经signal(SIGCHLD,SIG_IGN);那么子进程结束时,子进程的返回值不能被waitpid接收。
这个是必须关注的问题。
下面我们来分析system的实现:
下面给出system函数及SIGCHLD信号处理分别在2.6及2.4内核下的区别。system函数源码的一个实现如下:
int system(const char * cmdstring)
{
pid_t pid;
int status;
if(cmdstring == NULL)
{
return (1);
}
if((pid = fork())<0)
{
status = -1;
}
else if(pid == 0)
{
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
_exit(127);
}
else
{
while(waitpid(pid, &status, 0) < 0)
{
if(errno != EINTR)
{
status = -1;
break;
}
}
}
return status;
}
2.6内核下当父进程未调用wait系列函数等待子进程结束且未显式地忽略SIGCHLD信号,则子进程将成为僵死进程;(如果显示忽略,则子进程不僵死)
而在2.4内核中只要父进程未调用wait系列函数,则子进程就会成为僵死进程,不管是否显式地忽略SIGCHLD信号。
因而在SIGCHLD信号被显式忽略的情况下,2.6内核子进程将直接退出并释放资源,等父进程调用waitpid时,发现对应的pid进程已不存在,因而返回-1错误,errno为10(No child processes);
而在2.4内核下子进程在父进程waitpid之前不会退出,因而waitpid能成功获取子进程状态。
linux 系统信号忽略和system函数返回值问题(system的实现)相关推荐
- system函数返回值,Linux
理论 我们先看下man手册是怎么说的man system RETURN VALUEThe value returned is -1 on error (e.g., fork(2) failed), a ...
- system函数返回值
system(执行shell 命令) 相关函数 fork,execve,waitpid,popen 表头文件 #include<stdlib.h> 定义函数 int system(c ...
- system函数返回值探究
http://blog.chinaunix.net/uid-24774106-id-3048281.html?page=3 遇到system调用脚本,结果返回了256的情况,那么如何判断脚本是否正常成 ...
- Linux system函数返回值
例: status=system("./test.sh"); 1.先统一两个说法: (1)system返回值:指调用system函数后的返回值,比如上例中status为system ...
- perl system函数返回值问题
在Perl脚本中,允许调用系统的命令来进行操作.这就是Perl灵活性的体现,作为一种系统命令的粘合语言,能给程序员带来许多的便利.这样,你就可以最大限度地利用别人的成果,用不着自己使劲造轮子了. 在P ...
- ftok file php,Linux和PHP中的ftok函数返回值不一致问题跟踪
在IPC中中,我们经常事情ftok函数来获取key,来作为获取消息队列id.共享存储标识和信号量ID.在项目中使用了php进程和linux进程通信,采用了消息队列的方式,但是结果表现为php中的fto ...
- linux中signal函数返回值,signal函数、sigaction函数及信号集操作函数
信号是与一定的进程相联系的.也就是说一个进程可以决定在进程中对哪些信号进行什 么样的处理.例如一个进程可以忽略某些信号而只处理其他一些信号另外一个进程还可以选择如何处理信号.总之这些总与特定的进程相联 ...
- Linux中assert头文件,linux系统下如何使用assert函数
linux系统下如何使用assert函数 只要看得懂程序的人都知道assert,在Windows下使用VC编写,使用assert之后,只需在IDE中设置为debug版或者是release版,编译器就会 ...
- linux. qt信号崩溃,【创龙AM4379 Cortex-A9试用体验】之I/O中断异步通知驱动程序+QT捕获Linux系统信号+测试信号通知...
2.驱动程序 安装字符设备驱动程序开发流程开发. 2.1资源定义 定义按键I/O端口号.I/O中断号,以及字符设备的主设备号变量: #define GPIO_KEY1_PIN_NUM (3*32 + ...
- linux如何拿到文件的返回值,linux 下read函数返回值分析
原文出处:http://blog.chinaunix.net/space.php?uid=20558494&do=blog&id=2803003 read函数是Linux下不带缓存的文 ...
最新文章
- 仅为方便自己记忆一些滤波器【仅为考试】
- Android ANR产生的原理和如何避免
- 中兴ZXR10交换机配置手册
- seaborn系列 (14) | 条形图barplot()
- golang函数后的 {
- 【论文】引用格式 NoteExpress管理文献
- VS2008 ,TFS2008破解序列号
- python爬取万方数据库,python下载万方数据库文献
- php只取时间的下士_PHP 获取时间的各种处理方式!
- hr签核系统可以用python做吗_数字与签核参考流程
- linux 正则表达式和通配符
- python scrapy 基本操作演示代码
- (SQL)删除表中字段有中文的记录
- java ArrayList集合
- 新华三杯考前突击---Day2---IPV6技术篇
- JavaScript高级程序设计第四版
- 计算机中1kb等于多少字节,1kb等于多少个字节
- 【计算机毕业设计】外卖点餐源码
- 谈谈软件开发模式:瀑布与敏捷
- 360 ie8兼容模式 网页兼容问题