免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3628 | 回复: 1
打印 上一主题 下一主题

多线程和epoll 问题, epoll_wait 不返回 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-06-07 23:29 |只看该作者 |倒序浏览
多线程和epoll 问题, epoll_wait 不返回
设计的思想是这样的。

起一个子线程,这个线程称会不断建立与服务器的连接。

主线程则会 不断在epoll_wait 等待返回然后处理。  我这里epoll_wait 不返回。


通过网络监控 发现 子线程的的连接应该建立起来了

有三步握手了。 但我的程序一直不返回


还有2点 read write 的 阻塞和非阻塞有什么区别吗?

connect 的阻塞和非阻塞有什么区别?



  1. #include <pthread.h>
  2. #include <stdio.h>
  3. #include <sys/epoll.h>

  4. #include <sys/types.h>
  5. #include <sys/socket.h>
  6. #include <arpa/inet.h>
  7. #include <netdb.h>
  8. #include <unistd.h>
  9. #include <fcntl.h>


  10. #define maxevents 65535
  11. #define max_thread 6000

  12. void *work(void *arg);
  13. void setnonblocking(int sock);
  14. void do_use_fd(struct epoll_event   *events);

  15. int lines ;
  16. int epollfd = 0;
  17. int main(){
  18.         pthread_t pid_t;
  19.         struct epoll_event ev, *events;

  20.         int nfds = 0;       
  21.         int n = 0;
  22.         int status;
  23.                
  24.                 status = pthread_create(&pid_t, NULL, work, NULL);  // 起一个线称建立连接
  25.                
  26.                 if (status == 0) {               
  27.            printf(" %d created \n", n);
  28.                 } else {
  29.                                         printf(" %d create fail\n", n);
  30.           exit(0);
  31.    }
  32.    
  33.    epollfd  = epoll_create(maxevents);                   // 建立epoll
  34.    
  35.    if (-1 == epollfd){          
  36.       printf("error cannot epoll_create\n");
  37.       return 0;
  38.   }
  39.   
  40.   for (;;){
  41.            nfds = epoll_wait(epollfd, events, maxevents, -1); // 开始抓回复
  42.            for(n = 0; n < nfds; ++n) {
  43.                      printf("do do_use \n");              
  44.               do_use_fd(events+n);
  45.            }         
  46.   }       
  47.         return 0;
  48. }

  49. void *work(void *arg){  // 这个就是工作线称主要发起连接
  50.         int i = 0 ;
  51.         struct sockaddr_in clientadd;
  52.         int client;
  53.         struct epoll_event ev;
  54.         pthread_detach(pthread_self());  // this
  55.         int len = 0;
  56.         for (i = 0 ; i < 5 ;i ++){
  57.                
  58.                 sleep(10);
  59.           client = socket(AF_INET , SOCK_STREAM, 0);
  60.           if (client < 0){                 
  61.                   continue;       
  62.           }
  63.           printf("begin memset \n");
  64.           memset(&clientadd,0 , sizeof(clientadd));
  65.           clientadd.sin_family = AF_INET;
  66.           clientadd.sin_addr.s_addr  =  inet_addr("192.168.1.150");  
  67.           clientadd.sin_port  = htons(80);
  68.           setnonblocking(client);
  69.           
  70.           ev.events = EPOLLIN|EPOLLOUT |EPOLLERR;
  71.     ev.data.fd = client;
  72.     if (epoll_ctl(epollfd, EPOLL_CTL_ADD, client, &ev) < 0) {
  73.        fprintf(stderr, "epoll set insertion error: fd=%d",client);
  74.        return NULL;
  75.     }
  76.     printf("begin connect \n");
  77.     connect(client, (struct sockaddr*)&clientadd, sizeof(clientadd));
  78.     printf("begin connect \n");
  79.     sleep(5);
  80.        
  81.         }
  82. }

  83. void setnonblocking(int sock){
  84.         int opts;
  85.         opts=fcntl(sock,F_GETFL);
  86.         if(opts<0)
  87.         {
  88.                 perror("fcntl(sock,GETFL)");
  89.                 exit(1);
  90.         }

  91.         opts = opts|O_NONBLOCK;
  92.         if(fcntl(sock,F_SETFL,opts)<0)
  93.         {
  94.                 perror("fcntl(sock,SETFL,opts)");
  95.                 exit(1);
  96.         }
  97. }

  98. void do_use_fd(struct epoll_event   *events){
  99.         struct epoll_event ev;
  100.         int n ;
  101.         int client = events->data.fd;
  102.         char buff[] ="get / http/1.1\r\n\r\n";
  103.         char inbuff[1024] ={0};

  104.         if (events->events |EPOLLIN){ // 可以读了
  105.                 while (read(client, inbuff, 1024)){
  106.                   printf("%d  get 1024 \n", events->data.fd);       
  107.                 }
  108.                 /*
  109.                 ev.events = EPOLLOUT |EPOLLERR;
  110.     ev.data.fd = client;
  111.     if (epoll_ctl(epollfd, EPOLL_CTL_ADD, client, &ev) < 0) {
  112.        fprintf(stderr, "epoll set insertion error: fd=%d",client);
  113.        return -1;
  114.          */       
  115.                
  116.         }        else if (events->events |EPOLLOUT) {
  117.           write(events->data.fd, buff, strlen(buff));               
  118.           return ;       
  119.   }
  120.   
  121.   close(events->data.fd); //读完了 就短掉连接
  122.        
  123. }
复制代码

论坛徽章:
0
2 [报告]
发表于 2007-06-07 23:48 |只看该作者
好像明白了一点 epoll_ctl 要在epoll_Wait 以前执行

不然没有用


现在我的read 返回-1 。。。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP