1:signal的种类
2:使用signal实现系统sleep功能
static void sigHandler(int sig)
{
static int count = 0;
static int alarmcount = 0;
/* UNSAFE: This handler uses non-async-signal-safe functions
(printf(), exit(); see Section 21.1.2) */
if (sig == SIGINT) {
count++;
printf("Caught SIGINT (%d)\n", count);
return; /* Resume execution at point of interruption */
}
if(sig == SIGTERM)
{
exit(EXIT_SUCCESS);
}
if(sig ==SIGALRM)
{
alarmcount++;
printf("Caught SIGALRM (%d)\n", alarmcount);
}
/* Must be SIGQUIT - print a message and terminate the process */
return(EXIT_SUCCESS);
}
void alarmPause(int secs)
{
struct sigaction sa;
sa.sa_handler = sigHandler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGALRM, &sa, NULL);
sigaction(SIGHUP, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
#if 1
alarm(secs);
// printf("#####333######################\n");
pause(); /* Block until a signal is caught */
#endif
}
方法二
void sig_alrm(int signo)
{
/* nothing to do */
}
unsigned int mysleep(unsigned int nsecs)
{
struct sigaction newact, oldact;
unsigned int unslept;
newact.sa_handler = sig_alrm;
sigemptyset(&newact.sa_mask);
newact.sa_flags = 0;
sigaction(SIGALRM, &newact, &oldact);
alarm(nsecs);
pause();
unslept = alarm(0);
//sigaction(SIGALRM, &oldact, NULL);
return unslept;
}
三:fork()系统调用
void chlidFun()
{
while(1)
{
printf("Child PID = %ld\n", (long) getpid());
sleep(1);
}
}
void fkorkStatus()
{
int status;
pid_t childPid,pid;
//当进行fork调用时,一次调用会有俩次返回值出现。第二次为下面代码中的else部分。
pid =fork();
printf("fork() pid;%d\n",pid);
if(pid == -1)
{
errExit("fork");
}else if(0==pid)
{//Child:
printf("Child started with PID = %ld\n", (long) getpid());
chlidFun();
exit(EXIT_FAILURE); /* Not reached, but good practice */
printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
}
else
{ //Parent:
#if 0
//in federo 11 linux systerm ,next pid is paratent pid num
printf("waitpid 主要用来对其他进程进行同步PID = %ld\n", (long) getpid());
//其中waitpid中的参数为WUNTRACED时,进程将会阻塞。直到子进程返回即退出。
childPid = waitpid(-1, &status, WUNTRACED);
if (childPid == -1)
errExit("waitpid");
/* Print status in hex, and as separate decimal bytes */
printf("waitpid() returned: PID=%ld; status=0x%04x (%d,%d)\n",(long) childPid,(unsigned int) status, status >> 8, status & 0xff);
printWaitStatus(NULL, status);
if (WIFEXITED(status) || WIFSIGNALED(status))
// exit(EXIT_SUCCESS);
;
#endif
}
while(1)
{
printf("paraent PID = %ld\n", (long) getpid());
sleep(1);
}
}
在Unix系统编程中,常常会碰到两个概念:僵死进程和孤儿进程。话说我以前曾经把这两个概念弄混淆过。
什么是僵死进程?我们知道,在Unix进程模型中,进程是按照父进程产生子进程,子进程产生子子进程这样的方式创建出完成各项相互协作功能的进程的。当一个进程完成它的工作终止之后,它的父进程需要调用wait()或者waitpid()系统调用取得子进程的终止状态。如果父进程没有这么做的话,会产生什么后果呢?此时,子进程虽然已经退出了,但是在系统进程表中还为它保留了一些退出状态的信息,如果父进程一直不取得这些退出信息的话,这些进程表项就将一直被占用,此时,这些占着茅坑不拉屎的子进程就成为“僵死进程”(zombie)。系统进程表是一项有限资源,如果系统进程表被僵死进程耗尽的话,系统就可能无法创建新的进程。
那么,孤儿进程又是怎么回事呢?孤儿进程是指这样一类进程:在进程还未退出之前,它的父进程就已经退出了,一个没有了父进程的子进程就是一个孤儿进程(orphan)。既然所有进程都必须在退出之后被wait()或waitpid()以释放其遗留在系统中的一些资源,那么应该由谁来处理孤儿进程的善后事宜呢?这个重任就落到了init进程身上,init进程就好像是一个民政局,专门负责处理孤儿进程的善后工作。每当出现一个孤儿进程的时候,内核就把孤儿进程的父进程设置为init,而init进程会循环地wait()它的已经退出的子进程。这样,当一个孤儿进程“凄凉地”结束了其生命周期的时候,init进程就会代表党和政府出面处理它的一切善后工作。
这样来看,孤儿进程并不会有什么危害,真正会对系统构成威胁的是僵死进程。那么,什么情况下僵死进程会威胁系统的稳定呢?设想有这样一个父进程:它定期的产生一个子进程,这个子进程需要做的事情很少,做完它该做的事情之后就退出了,因此这个子进程的生命周期很短,但是,父进程只管生成新的子进程,至于子进程退出之后的事情,则一概不闻不问,这样,系统运行上一段时间之后,系统中就会存在很多的僵死进程,倘若用ps命令查看的话,就会看到很多状态为Z的进程。严格地来说,僵死进程并不是问题的根源,罪魁祸首是产生出大量僵死进程的那个父进程。因此,当我们寻求如何消灭系统中大量的僵死进程时,答案就是把产生大量僵死进程的那个元凶枪毙掉(也就是通过kill发送SIGTERM或者SIGKILL信号啦)。枪毙了元凶进程之后,它产生的僵死进程就变成了孤儿进程,这些孤儿进程会被init进程接管,init进程会wait()这些孤儿进程,释放它们占用的系统进程表中的资源,这样,这些已经“僵死”的孤儿进程就能瞑目而去了.
下面是孤儿进程和僵死进程的例子。
#if 0 时,进程状态:其中有一个僵死进程其状态为z。在执行过中,kill掉了子进程。即kill 5835
当上面为#if 1 时,输出结果及进程状态如下:
#if 1 时,进程状态为:在执行过中,kill掉了子进程。即kill 6079
下面举例一下fork()返回结果的实例
void waitchildexit()
{
pid_t pid;
pid = fork();
printf("pid:%d\n",pid);
if (pid < 0)
{
perror("fork failed");
exit(1);
}
if (pid == 0)
{
int i;
for (i = 3; i > 0; i--)
{
printf("This is the child\n");
sleep(1);
}
_exit(EXIT_SUCCESS);
}
else
{
int stat_val;
printf("pid:%d getpid:%d\n",pid,getpid());
waitpid(pid, &stat_val, 0);
if (WIFEXITED(stat_val))
{
printf("Child exited with code %d\n",WEXITSTATUS(stat_val));
}
else if (WIFSIGNALED(stat_val))
{
printf("Child terminated abnormally, signal %d\n",WTERMSIG(stat_val));
}
}
return 0;
}
其输出信息为:
int main(int argc, char *argv[])
{
fkorkStatus();
waitchildexit();
mysleep(2);
alarmPause(1);
}