1.实现过程
守护进程(编程流程):
- fork()退出父进程
- setsid()创建新会话
- fork()退出父进程(失去会话组长,进程组长的身份)
- 改变工作路径:chdir(“/”)改到根目录
- Umask掩码全部清零设置为000 (umask 0),掩码(002)中有什么权限,创建的文件就缺什么
- 关闭所有描述符close()
- //(关闭僵死进程)
Chkconfig查看后台的服务
UNIX第十三章
1.1实现源码
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<time.h>
int main()
{
//1.
//1. fork()退出父进程
//2. setsid()创建新会话
//3. fork()退出父进程(失去会话组长,进程组长的身份)
//4. 改变工作路径:chdir(“/”)改到根目录
//5. Umask掩码全部清零设置为000 (umask 0),掩码(002)中有什么权限,创建的文件就缺什么
//6. 关闭所有描述符close()
//7. //(关闭僵死进程)
if(fork()!=0)
{
exit(0);
}
setsid();
if(fork()!=0)
{
exit(0);
}
chdir("/");
umask(0);
int maxfd=getdtablesize();
int i=0;
for(;i<maxfd;i++)
{
close(i);
}
while(1)
{
FILE *fp=fopen("/tmp/yhxd.log","a");
if(fp==NULL)
{
break;
}
time_t tv;
time(&tv);
fprintf(fp,"Time is %s",asctime(localtime(&tv)));
fclose(fp);
sleep(5);
}
exit(0);
}
2.libevent库的使用
2.1代码实现
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/epoll.h>
#include<event.h>
#include<sys/time.h>
#include<errno.h>
#define MAXFD 1024
struct event *arr[MAXFD]={NULL};
void arr_add(int fd,struct event *ev)
{
if(fd<0 || fd>=MAXFD)
{
return;
}
arr[fd]=ev;
}
struct event *arr_find_ev(int fd)
{
if(fd<0||fd>=MAXFD)
{
return NULL;
}
struct event *ptr=arr[fd];
arr[fd]=NULL;
return ptr;
}
void recv_cb(int fd,short ev,void *arg)
{
if(ev& EV_READ)
{
char buff[128]={0};
int n=recv(fd,buff,127,0);
if(n<=0)
{
event_free(arr_find_ev(fd));
close(fd);
printf("one client over!!\n");
return;
}
printf("buff(%d)=%s\n",fd,buff);
send(fd,"ok",2,0);
}
}
void accept_cd(int fd,short ev,void *arg)
{
if(ev&EV_READ)
{
struct event_base* base=(struct event_base *)arg;
struct sockaddr_in caddr;
int len =sizeof(caddr);
int c=accept(fd,(struct sockaddr*)&caddr,&len);
if(c<0)
{
return ;
}
printf("accept c=%d\n",c);
struct event *c_ev=event_new(base,c,EV_READ|EV_PERSIST,recv_cb,NULL);
if(c_ev==NULL)
{
close(c);
return ;
}
event_add(c_ev,NULL);
arr_add(c,c_ev);
}
}
int main()
{
int sockfd=creat_sockfd();
assert(sockfd!=-1);
struct event_base *base=event_init();
assert(base!=NULL);
struct event *sock_ev=event_new(base,sockfd,EV_READ|EV_PERSIST,accept_cd,base);
assert(sock_ev!=NULL);
event_add(sock_ev,NULL);
event_base_dispatch(base);
event_free(sock_ev);
event_base_free(base);
close(sockfd);
exit(0);
}
int creat_sockfd()
{
int sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd==-1)
{
return -1;
}
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr));
saddr.sin_family =AF_INET;
saddr.sin_port =htons(6000);
saddr.sin_addr.s_addr=inet_addr("127.0.0.1");
//saddr.sin_addr.s_addr=inet((struct sockaddr*)&saddr,sizeof(saddr));
int res=bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
assert(res!=-1);
listen(sockfd,20);
return sockfd;
}
cli.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
int main()
{
int sockfd=socket(AF_INET,SOCK_STREAM,0);
assert(sockfd!=-1);
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr));
saddr.sin_family=AF_INET;
saddr.sin_port=htons(6000);
saddr.sin_addr.s_addr=inet_addr("127.0.1");
int res=connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
assert(res!=-1);
while(1)
{
char buff[128]={0};
printf("input:\n");
fgets(buff,128,stdin);
if(strncmp(buff,"end",3)==0)
{
break;
}
send(sockfd,buff,strlen(buff),0);
memset(buff,0,128);
recv(sockfd,buff,127,0);
printf("buff=%s\n",buff);
}
close(sockfd);
}
2.3libevent 库的实现过程

本文详细介绍了守护进程的创建过程及libevent库的使用方法。守护进程通过fork、setsid等步骤脱离终端,实现后台运行。libevent库则通过事件驱动模型,实现了高效的网络I/O处理,适用于高并发场景。
644

被折叠的 条评论
为什么被折叠?



