fork守护进程

学习网址:

学习笔记:fork实现守护进程
https://blog.csdn.net/u010312436/article/details/81778865


1.进程产生的信号:

/**
1 	SIGHUP 	挂起 	 
2 	SIGINT 	中断 	 
3 	SIGQUIT 	退出 	 
4 	SIGILL 	非法指令 	 
5 	SIGTRAP 	断点或陷阱指令 	 
6 	SIGABRT 	abort发出的信号 	 
7 	SIGBUS 	非法内存访问 	 
8 	SIGFPE 	浮点异常 	 
9 	SIGKILL 	kill信号 	不能被忽略、处理和阻塞
10 	SIGUSR1 	用户信号1 	 
11 	SIGSEGV 	无效内存访问 	 
12 	SIGUSR2 	用户信号2 	 
13 	SIGPIPE 	管道破损,没有读端的管道写数据 	 
14 	SIGALRM 	alarm发出的信号 	 
15 	SIGTERM 	终止信号 	 
16 	SIGSTKFLT 	栈溢出 	 
17 	SIGCHLD 	子进程退出 	默认忽略
18 	SIGCONT 	进程继续 	 
19 	SIGSTOP 	进程停止 	不能被忽略、处理和阻塞
20 	SIGTSTP 	进程停止 	 
21 	SIGTTIN 	进程停止,后台进程从终端读数据时 	 
22 	SIGTTOU 	进程停止,后台进程想终端写数据时 	 
23 	SIGURG 	I/O有紧急数据到达当前进程 	默认忽略
24 	SIGXCPU 	进程的CPU时间片到期 	 
25 	SIGXFSZ 	文件大小的超出上限 	 
26 	SIGVTALRM 	虚拟时钟超时 	 
27 	SIGPROF 	profile时钟超时 	 
28 	SIGWINCH 	窗口大小改变 	默认忽略
29 	SIGIO 	I/O相关 	 
30 	SIGPWR 	关机 	默认忽略
31 	SIGSYS 	系统调用异常
**/
//引用网址: https://blog.csdn.net/u010312436/article/details/81778865


2.fork的返回值

fork会返回两次,返回值:

(1) >0   在父进程中,fork返回新创建子进程的进程ID; 注意这里是返回"子进程的pid"
(2) ==0 在子进程中,fork返回0;
(3) <0   如果出现错误,fork返回一个负值。

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
 
int main(int argc,char *argv[]){
    pid_t pid=fork();
    if ( pid < 0 ) {
        fprintf(stderr,"错误!");
    } else if( pid == 0 ) {
        printf("子进程空间");
        exit(0);
    } else {
        printf("父进程空间,子进程pid为%d",pid);
    }
    // 可以使用wait或waitpid函数等待子进程的结束并获取结束状态
    exit(0);
}

3 waitpid函数

#include <sys/types.h> 
#include <sys/wait.h>
pid_t waitpid(pid_t pid,int *status,int options); 

调用waitpid()函数时两种情况
<1>当指定等待的子进程已经停止运行或结束了,则waitpid()会立即返回;
<2>当子进程还没有停止运行或结束,则调用waitpid()函数的父进程则会被阻塞,暂停运行。

学习资料:

Linux中waitpid()函数的用法
https://blog.csdn.net/Roland_Sun/article/details/32084825 

4.守护进程例子 

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


#include <iostream>

void startDaemon() {
#ifndef _WIN32
  static pid_t pid;
  do {
    pid = fork();
    if (pid < 0) {
      std::cout << "fork失败: pid=" << pid << std::endl;

      //休眠1秒再试
      sleep(1);
      continue;
    }

    if (pid == 0) {
      //子进程
      return;
    }

    //父进程,监视子进程是否退出
    std::cout << "启动子进程:pid=" << pid << std::endl;
    signal(SIGINT, [](int) {
      std::cout << "收到主动退出信号,关闭父进程与子进程" << std::endl;
      kill(pid, SIGINT);
      exit(0);
    });

    //父进程守护子进程,子进程崩了后,父进程再调一次fork
    do {
      int status = 0;
      if (waitpid(pid, &status, 0) >= 0) {
        std::cout << "子进程退出" << std::endl;
        //休眠1秒再启动子进程
        sleep(1);
        break;
      }
      
      std::cout << "waitpid被中断:" << strerror(errno)<<std::endl;
    } while (true);

  } while (true);
#endif  // _WIN32
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值