Linux16,17守护进程的实现,libevent库的使用

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

1.实现过程

守护进程(编程流程):

  1. fork()退出父进程
  2. setsid()创建新会话
  3. fork()退出父进程(失去会话组长,进程组长的身份)
  4. 改变工作路径:chdir(“/”)改到根目录
  5. Umask掩码全部清零设置为000 (umask 0),掩码(002)中有什么权限,创建的文件就缺什么
  6. 关闭所有描述符close()
  7. //(关闭僵死进程)
    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 库的实现过程

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我的sun&shine

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值