Chinaunix首页 | 论坛 | 博客
  • 博客访问: 416939
  • 博文数量: 124
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 872
  • 用 户 组: 普通用户
  • 注册时间: 2018-03-29 14:38
个人简介

默默的一块石头

文章分类

全部博文(124)

文章存档

2022年(26)

2021年(10)

2020年(28)

2019年(60)

我的朋友

分类: LINUX

2022-01-17 10:07:53

#include stdio.h 
#include sys/types.h 
#include sys/socket.h 
#include unistd.h 
#include sys/epoll.h 
#include netdb.h 
#include stdlib.h 
#include fcntl.h 
#include sys/wait.h 
#include errno.h 
#define PROCESS_NUM 4
#define MAXEVENTS 64

#define MAXLINE 80
#define SERV_PORT 9999
#define OPEN_MAX 526

static int pidnum[PROCESS_NUM],epfd[PROCESS_NUM];
void create(int listenfd,int num);
typedef struct {
    int fd[2];
} eptest;
int main(int argc, char *argv[])
{
    int i,r;
    eptest epdata[5];
    struct sockaddr_in servaddr,cliaddr;
    socklen_t cliaddr_len;
    int listenfd,connfd,sockfd;
    int nready,efd,res,client[OPEN_MAX];
    ssize_t n;
    char buf[MAXLINE];
    char str[INET_ADDRSTRLEN];
    
    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    printf("listenfd:%d\n",listenfd);


    bzero(&servaddr, sizeof(servaddr));
    //ipv4 
    servaddr.sin_family= AF_INET;
    //ip 
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    //port
    servaddr.sin_port= htons(SERV_PORT);

    bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    //设置同时能够接受128个请求,注意是同一时间
    listen(listenfd, 128);
    printf("pid = %d\n",getpid());
    for(i = 0;i < PROCESS_NUM;i++){
    r = socketpair(AF_UNIX, SOCK_STREAM, 0, epdata[i].fd);
    if (r < 0){
        perror( "socketpair()" );
        exit(1);
    }
    create(listenfd,i);
    }
    printf("pid1 = %d i = %d\n",getpid(),i);
    while(1);
 
    return 0;
}

void create(int listenfd,int num){
  int epoll_fd,pid;
  struct epoll_event event;
  struct epoll_event events;
  struct epoll_event tep,ep;

  pid = fork();
  /*switch (pid) {
    case -1:
        return -1;
    case 0:
        break;
    default:
        return 0;
  }*/
 if(pid == 0){ 
  pidnum[num] = getpid();  

  if((epoll_fd = epoll_create(MAXEVENTS))< 0){
        perror("epoll_create");
        exit(1);
  }
  event.data.fd = listenfd;
  event.events = EPOLLIN | EPOLLEXCLUSIVE;
  if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listenfd, &event) < 0){
        perror("epoll_ctl");
        exit(1);
  }
  printf("pidnum[%d] = %d pid = %d epoll_fd = %d\n",num,pidnum[num],getpid(),epoll_fd); 
  while(1){
                int num, j,i;
                num = epoll_wait(epoll_fd, &events, MAXEVENTS, -1);
                printf("process %d returnt from epoll_wait epoll_fd = %d\n", getpid(),epoll_fd);
sleep(2);
                    if((events.events & EPOLLERR) || (events.events & EPOLLHUP) || (!(events.events & EPOLLIN))){
                        fprintf(stderr, "epoll error\n");
                        close(events.data.fd);
                        continue;
                    }else if(listenfd == events.data.fd){
                        //收到关于监听套接字的通知,意味着一盒或者多个传入连接
                        struct sockaddr in_addr;
                        socklen_t in_len = sizeof(in_addr);
                        if(accept(listenfd, &in_addr, &in_len) < 0){
                            printf("process %d accept failed!\n", getpid());
                        }else{
                            printf("process %d accept successful!\n", getpid());
                        }
                    }
                
 }
}
}

----------------------------------linux-5.4.1
/*
 * Must be called with "mtx" held.
 */
static int ep_insert(struct eventpoll *ep, const struct epoll_event *event,
     struct file *tfile, int fd, int full_check)
{
int error, pwake = 0;
__poll_t revents;
long user_watches;
struct epitem *epi;
struct ep_pqueue epq;

lockdep_assert_irqs_enabled();

user_watches = atomic_long_read(&ep->user->epoll_watches);
if (unlikely(user_watches >= max_user_watches))
return -ENOSPC;
if (!(epi = kmem_cache_alloc(epi_cache, GFP_KERNEL)))
return -ENOMEM;

/* Item initialization follow here ... */
INIT_LIST_HEAD(&epi->rdllink);
INIT_LIST_HEAD(&epi->fllink);
INIT_LIST_HEAD(&epi->pwqlist);
epi->ep = ep;
ep_set_ffd(&epi->ffd, tfile, fd);
epi->event = *event;
epi->nwait = 0;
epi->next = EP_UNACTIVE_PTR;
if (epi->event.events & EPOLLWAKEUP) {
error = ep_create_wakeup_source(epi);
if (error)
goto error_create_wakeup_source;
} else {
RCU_INIT_POINTER(epi->ws, NULL);
}

/* Initialize the poll table using the queue callback */
epq.epi = epi;
/*
/*
 * This is the callback that is used to add our wait queue to the
 * target file wakeup lists.
 */
static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead,
poll_table *pt)
{
struct epitem *epi = ep_item_from_epqueue(pt);
struct eppoll_entry *pwq;

if (epi->nwait >= 0 && (pwq = kmem_cache_alloc(pwq_cache, GFP_KERNEL))) {
init_waitqueue_func_entry(&pwq->wait, ep_poll_callback);
pwq->whead = whead;
pwq->base = epi;
if (epi->event.events & EPOLLEXCLUSIVE)
add_wait_queue_exclusive(whead, &pwq->wait);
else
add_wait_queue(whead, &pwq->wait);
list_add_tail(&pwq->llink, &epi->pwqlist);
epi->nwait++;
} else {
/* We have to signal that an error occurred */
epi->nwait = -1;
}
}

*/
init_poll_funcptr(&epq.pt, ep_ptable_queue_proc);
}
阅读(368) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~