乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      線程池epoll

       jijo 2008-09-25
      標(biāo)題   linux 2.6內(nèi)核epoll用法舉例說明(續(xù))--給echo服務(wù)器增加讀線程池     選擇自 mote_li 的 Blog
      關(guān)鍵字   linux 2.6內(nèi)核epoll用法舉例說明(續(xù))--給echo服務(wù)器增加讀線程池
      出處  
      上篇文章使用linux內(nèi)核2.6提供的epoll機(jī)制實(shí)現(xiàn)了一個(gè)反應(yīng)式echo服務(wù)器,使用反應(yīng)式服務(wù)器的最大好處就是可以按cpu的數(shù)量來配置線程池內(nèi)線程的線程數(shù)而不是根據(jù)客戶端的并發(fā)量配置線程池。我是第一次使用pthread庫來寫線程池,使用的是工作隊(duì)列方式的線程池。我感覺作隊(duì)列方式的線程池可以當(dāng)成一種設(shè)計(jì)模式來用的,在很多平臺(tái)上都是可以按這種方式來實(shí)現(xiàn)線程池,從win32 ,unix到j(luò)vm都是適用的

       

      #include <iostream>

      #include <sys/socket.h>

      #include <sys/epoll.h>

      #include <netinet/in.h>

      #include <arpa/inet.h>

      #include <fcntl.h>

      #include <unistd.h>

      #include <stdio.h>

      #include <pthread.h>

       

      #define MAXLINE 10

      #define OPEN_MAX 100

      #define LISTENQ 20

      #define SERV_PORT 5555

      #define INFTIM 1000

       

      //線程池任務(wù)隊(duì)列結(jié)構(gòu)體

      struct task{

        int fd;            //需要讀寫的文件描述符

        struct task *next; //下一個(gè)任務(wù)

      };

       

      //用于讀寫兩個(gè)的兩個(gè)方面?zhèn)鬟f參數(shù)

      struct user_data{

        int fd;

        unsigned int n_size;

        char line[MAXLINE];

      };

       

      //線程的任務(wù)函數(shù)

      void * readtask(void *args);

      void * writetask(void *args);

       

       

      //聲明epoll_event結(jié)構(gòu)體的變量,ev用于注冊(cè)事件,數(shù)組用于回傳要處理的事件

      struct epoll_event ev,events[20];

      int epfd;

      pthread_mutex_t mutex;

      pthread_cond_t cond1;

      struct task *readhead=NULL,*readtail=NULL,*writehead=NULL;

       

      void setnonblocking(int sock)

      {

           int opts;

           opts=fcntl(sock,F_GETFL);

           if(opts<0)

           {

                perror("fcntl(sock,GETFL)");

                exit(1);

           }

          opts = opts|O_NONBLOCK;

           if(fcntl(sock,F_SETFL,opts)<0)

           {

                perror("fcntl(sock,SETFL,opts)");

                exit(1);

           }   

      }

       

      int main()

      {

           int i, maxi, listenfd, connfd, sockfd,nfds;

           pthread_t tid1,tid2;

          

           struct task *new_task=NULL;

           struct user_data *rdata=NULL;

           socklen_t clilen;

          

           pthread_mutex_init(&mutex,NULL);

           pthread_cond_init(&cond1,NULL);

           //初始化用于讀線程池的線程

           pthread_create(&tid1,NULL,readtask,NULL);

           pthread_create(&tid2,NULL,readtask,NULL);

          

           //生成用于處理acceptepoll專用的文件描述符   

           epfd=epoll_create(256);

       

           struct sockaddr_in clientaddr;

           struct sockaddr_in serveraddr;

           listenfd = socket(AF_INET, SOCK_STREAM, 0);

           //socket設(shè)置為非阻塞方式

           setnonblocking(listenfd);

           //設(shè)置與要處理的事件相關(guān)的文件描述符

           ev.data.fd=listenfd;

           //設(shè)置要處理的事件類型

           ev.events=EPOLLIN|EPOLLET;

           //注冊(cè)epoll事件

           epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev);

          

           bzero(&serveraddr, sizeof(serveraddr));

           serveraddr.sin_family = AF_INET;

          

           char *local_addr="200.200.200.222";

           inet_aton(local_addr,&(serveraddr.sin_addr));//htons(SERV_PORT);

           serveraddr.sin_port=htons(SERV_PORT);

           bind(listenfd,(sockaddr *)&serveraddr, sizeof(serveraddr));

           listen(listenfd, LISTENQ);

          

           maxi = 0;

           for ( ; ; ) {

                //等待epoll事件的發(fā)生

                nfds=epoll_wait(epfd,events,20,500);

                //處理所發(fā)生的所有事件     

              for(i=0;i<nfds;++i)

              {

                     if(events[i].data.fd==listenfd)

                     {

                         

                          connfd = accept(listenfd,(sockaddr *)&clientaddr, &clilen);

                          if(connfd<0){

                            perror("connfd<0");

                            exit(1);

                         }

                          setnonblocking(connfd);

                         

                          char *str = inet_ntoa(clientaddr.sin_addr);

                          std::cout<<"connec_ from >>"<<str<<std::endl;

                          //設(shè)置用于讀操作的文件描述符

                          ev.data.fd=connfd;

                          //設(shè)置用于注測的讀操作事件

                       ev.events=EPOLLIN|EPOLLET;

                          //注冊(cè)ev

                       epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);

                     }

                  else if(events[i].events&EPOLLIN)

                  {

                          printf("reading!\n");                

                          if ( (sockfd = events[i].data.fd) < 0) continue;

                          new_task=new task();

                          new_task->fd=sockfd;

                          new_task->next=NULL;

                          //添加新的讀任務(wù)

                          pthread_mutex_lock(&mutex);

                          if(readhead==NULL)

                          {

                            readhead=new_task;

                            readtail=new_task;

                          }   

                          else

                          {   

                           readtail->next=new_task;

                            readtail=new_task;

                          }   

                         //喚醒所有等待cond1條件的線程

                          pthread_cond_broadcast(&cond1);

                          pthread_mutex_unlock(&mutex);  

                    }

                     else if(events[i].events&EPOLLOUT)

                     {   

                    rdata=(struct user_data *)events[i].data.ptr;

                       sockfd = rdata->fd;

                       write(sockfd, rdata->line, rdata->n_size);

                       delete rdata;

                       //設(shè)置用于讀操作的文件描述符

                       ev.data.fd=sockfd;

                       //設(shè)置用于注測的讀操作事件

                     ev.events=EPOLLIN|EPOLLET;

                       //修改sockfd上要處理的事件為EPOLIN

                     epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);

                     }

                                   

                }

               

           }

      }

      void * readtask(void *args)

      {

         

         int fd=-1;

         unsigned int n;

         //用于把讀出來的數(shù)據(jù)傳遞出去

         struct user_data *data = NULL;

         while(1){

              

              pthread_mutex_lock(&mutex);

              //等待到任務(wù)隊(duì)列不為空

              while(readhead==NULL)

                   pthread_cond_wait(&cond1,&mutex);

              

              fd=readhead->fd;

              //從任務(wù)隊(duì)列取出一個(gè)讀任務(wù)

              struct task *tmp=readhead;

              readhead = readhead->next;

              delete tmp;

              pthread_mutex_unlock(&mutex);

              data = new user_data();

              data->fd=fd;

              if ( (n = read(fd, data->line, MAXLINE)) < 0) {

                 

                 if (errno == ECONNRESET) {

                   close(fd);

                   

                } else

                   std::cout<<"readline error"<<std::endl;

                 if(data!=NULL)delete data;

              } else if (n == 0) {

                  close(fd);

                 printf("Client close connect!\n");

                 if(data!=NULL)delete data;

              } else{

              

              data->n_size=n;

              //設(shè)置需要傳遞出去的數(shù)據(jù)

              ev.data.ptr=data;

              //設(shè)置用于注測的寫操作事件

              ev.events=EPOLLOUT|EPOLLET;

              //修改sockfd上要處理的事件為EPOLLOUT

              epoll_ctl(epfd,EPOLL_CTL_MOD,fd,&ev);

             }

         }

      }

       



        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多