守护进程
守护进程创建
/************************************************************************* > File Name: daemon.c > Author: ICKelin > Mail: [email protected] > Created Time: 2014年12月18日 星期四 01时04分59秒 ************************************************************************/ #include<stdio.h> #include <sys/resource.h> #include <fcntl.h> #include <syslog.h> #include <signal.h> #include <stdlib.h> /* * 守护进程 * 守护进程 * 创建守护进程 * umask(0) * fork()&exit(0) * setsid() * chdir() * getrlimit&close(i) * * */ void daemonize(const char *cmd) { int i,fd0, fd1, fd2; pid_t pid; struct rlimit rl; struct sigaction sa; //清除 umask(0); //获取最大文件描述符号 if(getrlimit(RLIMIT_NOFILE, &rl) < 0) error("getrlimit"); //会话组,进程组组长 if( (pid = fork()) < 0) error("fork"); else if(pid > 0) exit(0); //停止父进程 setsid(); sa.sa_handler = SIG_IGN; //忽略 sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if(sigaction(SIGHUP, &sa, NULL) < 0) error("ignore SIGHUB"); if((pid = fork()) < 0) error("fork"); else if(pid != 0) exit(0); //修改当前工作路径 if(chdir("/") < 0) error("chdir"); //关闭文件描述符 for(i = 0; i< rl.rlim_max; i++) close(i); fd0 = open("/dev/null", O_RDWR); fd1 = dup(0); fd2 = dup(0); //初始化log openlog(cmd, LOG_CONS, LOG_DAEMON); if(fd0 !=0 || fd1 != 1 || fd2 != 2) { syslog(LOG_ERR,"unexpected file descriptors %d %d %d", fd0, fd1, fd2); exit(1); } } int main(int argc,char *argv[]) { daemonize("daemon"); }
服务器端守护进程
/************************************************************************* > File Name: demo04.c > Author: ICKelin > Mail: [email protected] > Created Time: 2014年12月07日 星期日 15时17分48秒 ************************************************************************/ #include"net.h" #include <syslog.h> #include <fcntl.h> #include <signal.h> #include <sys/resource.h> void daemonize(const char *cmd) { int i,fd0, fd1, fd2; pid_t pid; struct rlimit rl; struct sigaction sa; //清除 umask(0); //获取最大文件描述符号 if(getrlimit(RLIMIT_NOFILE, &rl) < 0) error("getrlimit"); //会话组,进程组组长 if( (pid = fork()) < 0) error("fork"); else if(pid > 0) exit(0); //停止父进程 setsid(); sa.sa_handler = SIG_IGN; //忽略 sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if(sigaction(SIGHUP, &sa, NULL) < 0) error("ignore SIGHUB"); if((pid = fork()) < 0) error("fork"); else if(pid != 0) exit(0); //修改当前工作路径 if(chdir("/") < 0) error("chdir"); //关闭文件描述符 for(i = 0; i< rl.rlim_max; i++) close(i); fd0 = open("/dev/null", O_RDWR); fd1 = dup(0); fd2 = dup(0); //初始化log openlog(cmd, LOG_CONS, LOG_DAEMON); if(fd0 !=0 || fd1 != 1 || fd2 != 2) { syslog(LOG_ERR,"unexpected file descriptors %d %d %d", fd0, fd1, fd2); exit(1); } } int main(int argc,char *argv[]) { if(argc != 2) error("arguemtne"); daemonize("server"); unsigned int port = atoi( argv[1]); int server = setup(port); if(server ==-1) error("setup"); fprintf(stdout,"server start\nlistenning port %d\n",port); struct sockaddr_storage client_addr; unsigned int address_size = sizeof(client_addr); while(1) { int client = accept(server,(struct sockaddr*)&client_addr,&address_size); do_connect(client,client_thread,(void *)client); } close(server); return 0; }
net.h头文件
/************************************************************************* > File Name: demo03.c > Author: ICKelin > Mail: [email protected] > Created Time: 2014年12月07日 星期日 11时53分24秒 ************************************************************************/ #include<stdio.h> #include<stdlib.h> #include<sys/socket.h> #include<arpa/inet.h> #include<string.h> #include<errno.h> #include<pthread.h> #include<unistd.h> static int count = 0; /* 致命错误处理包裹函数 */ void error(char *msg) { fprintf(stderr,"%s error with:%s\n",msg, strerror(errno)); exit(1); } /* 服务器启动函数 * 接收端口号 * 绑定,监听 * 返回服务器端套接字描述符 * * */ int setup(unsigned int port) { struct sockaddr_in server_sock; int fd = -1; fd = socket(PF_INET, SOCK_STREAM, 0); int reuse = 1; if(setsockopt(fd,SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(int)) == -1) error("set reuse"); if(fd == -1) error("socket"); server_sock.sin_family = PF_INET; server_sock.sin_port = (in_port_t)htons(port); server_sock.sin_addr.s_addr = htonl(INADDR_ANY); int c = bind(fd, (struct sockaddr *)&server_sock, sizeof(server_sock)); if(c == -1) error("bind"); if(listen(fd,10) == -1) error("listen"); return fd; } /* 连接处理线程 * * 接收连接套接子描述符 * 处理请求 * 返回空 * */ void client_thread(int connect_d) { char *msg = "welcome to my server --ICKelin\n"; fprintf(stdout,"new connect, current connect count %d\n",++count); sleep(5); if(send(connect_d, msg, strlen(msg),0) <0) { error("send"); } close(connect_d); count--; } /* * 处理连接 * 接收客户端连接,和处理线程 * 返回空 * */ void do_connect(int connect_d,void *func,void *args) { pthread_t newthread; if ( pthread_create(&newthread,NULL,func,args) == -1) error("pthread_create"); } /* * 关闭连接 * */ void close_connect(int fd) { close(fd); }
由于前后编写时间间隔比较长,代码前后搭配不当,正确的做法是,将net.h里面输出到标准输出,标准错误相关代码利用syslog输出到日志。
编译执行
hadoop@ICKelin:~/Network/2014_12_07$ gcc demo04.c -lpthread -o myserver1111111 hadoop@ICKelin:~/Network/2014_12_07$ ./myserver1111111 5002 hadoop@ICKelin:~/Network/2014_12_07$ ps -axj|grep myserver1111111 Warning: bad ps syntax, perhaps a bogus ‘-‘? See http://procps.sf.net/faq.html 1 8313 8312 8312 ? -1 S 1000 0:00 ./myserver1111111 5002 8035 8319 8318 8035 pts/0 8318 S+ 1000 0:00 grep --color=auto myserver1111111 hadoop@ICKelin:~/Network/2014_12_07$
用kill杀死。kill 8313
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。