说说服务端编程那些事儿---守护进程

  上一篇我们讲了后台进程,本篇我们来讲讲守护进程。

  有人会问,守护进程是什么样的进程呢?他和前面介绍的普通进程及后台进程又有什么区别呢?

  其实守护进程和后台进程一样,也是不依赖于终端,父进程是操作,运行于后端的进程。它和后端进程的最大的特点是它具备捕获并处理信号的能力。

  他是怎么做到这些的呢?

  Linux系统中,提供了信号量处理函数,他们用于捕获运行过程中收到的信号并处理他们。而守护进程正是使用了这些函数的后台进程。

  下面让我们来看看如何实现它

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

void catchSignal(int nSign)

{

void *array[10];

std::size_t size;

size = backtrace(array, 10);

int save_fd = dup(STDOUT_FILENO); //将标准输出重定向到文件

char bufBtFileName[512] = {0};

sprintf(bufBtFileName, "/tmp/%s.bt", GetProcessName());

int fd = open(bufBtFileName, (O_RDWR | O_CREAT), 0644);

dup2(fd,STDOUT_FILENO);

char **strings = backtrace_symbols(array, size);

for (int i = 0; i < size; i++)

printf( "%s\n", strings[i]);

free(strings);

char cmd[64] = "addr2line -C -f -e ";

char* prog = cmd + strlen(cmd);

readlink("/proc/self/exe", prog, sizeof(cmd) - strlen(cmd) - 1);// 获取进程的完整路径

FILE* fp = popen(cmd, "w");

if (fp != NULL)

{

for (int i = 0; i < size; ++i)

{

fprintf(fp, "%p\n", array[i]);

}

pclose(fp);

}

exit(0);

}

void setProcSignal()

{

signal( SIGINT,  SIG_IGN);

signal( SIGHUP,  SIG_IGN);

signal( SIGQUIT, SIG_IGN);

signal( SIGPIPE, SIG_IGN);

signal( SIGTTOU, SIG_IGN);

signal( SIGTTIN, SIG_IGN);

signal( SIGCHLD, SIG_IGN);

signal( SIGTERM, SIG_IGN);

signal( SIGHUP, SIG_IGN);

struct sigaction sig;

    sig.sa_handler = catchSignal;

    sigemptyset(&sig.sa_mask);

    sig.sa_flags = SA_RESTART | SA_SIGINFO;

    sigaction(SIGSEGV, &sig, NULL); // 无效内存引用

    sigaction(SIGABRT, &sig, NULL); // 异常终止

}

void deamon_init()

{

pid_t pid;

if ((pid = fork()) != 0) exit(0);

setsid();

if ((pid = fork()) != 0) exit(0);

rlimit rlim;

if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)

{

for (int fd = 3; fd <= (int)rlim.rlim_cur; fd++)

{

close(fd);

}

}

umask(0);

setpgrp();

int fd = -1;

if ((fd = open("/dev/null", O_RDWR)) == -1) exit(1);

dup2(fd, STDIN_FILENO);

dup2(fd, STDERR_FILENO);

close(fd);

return 0;

}

int main()

{

deamon_init();

setProcSignal();

return 0;

}

你可能感兴趣的:(说说服务端编程那些事儿---守护进程)