免费注册 查看新帖 |

Chinaunix

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

[Linux] C 多线程,执行异常了,顺序影响执行结果? [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-02-10 19:59 |只看该作者 |倒序浏览
执行结果:



代码中,在udp_process();里封装了一个UDP的接受代码(网上找到),函数启动了一个线程。

将该udp_process();函数,放在两个打印字符的线程,后面执行,结果如上图,三个线程都正常工作
  1. void main(int argc, char **argv)
  2. {       
  3.          initMutex();
  4.          initial_udp();
  5.          
  6.                
  7.                 //udp_process();
  8.                  /*
  9.         初始化属性值,均设为默认值
  10.         */   
  11.          
  12.         pthread_attr_init(&attr2);
  13.         pthread_attr_setscope(&attr2, PTHREAD_SCOPE_SYSTEM);        
  14.         pthread_attr_setdetachstate(&attr2, PTHREAD_CREATE_DETACHED);
  15.                
  16.                  if(pthread_create(&thread_loop_print,&attr2,(void*)pthread_handle_message2,NULL))
  17.     {
  18.             perror("pthread_creat error!");
  19.       exit(-1);
  20.     }
  21.    
  22.      if(pthread_create(&thread_loop_print2,&attr2,(void*)pthread_handle_message3,NULL))
  23.     {
  24.             perror("pthread_creat error!");
  25.       exit(-1);
  26.     }
  27.    
  28.                  udp_process();
  29.                  
  30.                  pthread_join (thread_loop_print, NULL);
  31.                  pthread_join (thread_loop_print2, NULL);
  32.                  pthread_join (thread_udp_process, NULL);
  33.           while(1)
  34.      {
  35.              sleep(1);
  36.              }
  37.           //return 0;
  38.        
  39. }
复制代码
在代码中,
udp_process();函数先执行时, 结果如下图:
两个打印字符串的线程,没有执行,, 只有处理UDP 数据包的 线程正确执行,

顺序很有影响么?





论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2015-02-11 00:11 |只看该作者

  1. #include "udp.h"


  2.   /*
  3.   创建 EPOLL 句柄,
  4.   */

  5. int create_epoll_udp(unsigned int event_num)
  6. {
  7.         int epoll_fd;
  8.        
  9.         epoll_fd= epoll_create(event_num);  
  10.   len = sizeof(struct sockaddr_in);
  11.   ev.events = EPOLLIN | EPOLLET;
  12.   ev.data.fd = listener;
  13.   if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listener, &ev) < 0)
  14.   {
  15.     fprintf(stderr, "epoll set insertion error: fd=%d \n", listener);
  16.     return -1;
  17.   }
  18.   else
  19.   {
  20.     printf("socket adding in  epoll success! \n");
  21.   }
  22.   
  23.         return epoll_fd;
  24.        
  25.         }
  26.        

  27.        
  28.        
  29. /*
  30. setnonblocking--设置具备为非阻塞方式
  31. */
  32. int setnonblocking(int sockfd)
  33. {
  34.   if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1)
  35.   {
  36.     return -1;
  37.   }
  38.   return 0;
  39. }


  40. /*
  41. pthread_handle_message --线程处理 socket上的消息收发
  42.   */
  43.   
  44. void* pthread_handle_message2()
  45. {
  46.         while(1){
  47.                 printf("this is thread 2!\n");
  48.                 fflush(stdout);
  49.                 sleep(1);
  50.                 //pthread_exit(NULL);
  51.         }
  52. }
  53. void* pthread_handle_message3()
  54. {
  55.         while(1){
  56.                 printf("this is thread 3!\n");
  57.                 printf("\n");
  58.                 fflush(stdout);
  59.                 sleep(3);
  60.                 //pthread_exit(NULL);
  61.         }
  62. }

  63. void* pthread_handle_message(int* sock_fd)
  64. {
  65.         int i;
  66.         int ret_data_len;
  67.   unsigned char recvbuf[MAXBUF + 1];
  68.   unsigned char sendbuf[MAXBUF+1];
  69.   int  ret;
  70.   int  new_fd;
  71.   struct sockaddr_in client_addr;
  72.   socklen_t cli_len=sizeof(client_addr);
  73.   new_fd=*sock_fd;

  74.   /*
  75.   
  76.   开始处理每个新连接上的数据收发
  77.   */
  78.   bzero(recvbuf, MAXBUF + 1);
  79.   bzero(sendbuf, MAXBUF + 1);

  80.   /*
  81.   接收客户端的消息
  82.   */
  83.   
  84.   
  85.   ret = recvfrom(new_fd, recvbuf, MAXBUF, 0, (struct sockaddr *)&client_addr, &cli_len);
  86.   if (ret > 0)
  87.           {
  88.             printf("socket %d recv from : %s : %d message: %s  %d bytes \n",
  89.            new_fd, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), recvbuf, ret);
  90.              printf("Hex bytes: \n");
  91.             
  92.              if(recvbuf[0]==0x40)
  93.                      {       
  94.                              for(i=0;i<recvbuf[1]+2;i++)
  95.                               printf("%02X",recvbuf[i]);
  96.                              printf("\n");       
  97.                              printf("\n");       
  98.                              if(recvbuf[2]==CMD_GET_VERSION)
  99.                                      {
  100.                                              ret_data_len = getVersionInfo(sendbuf);                                                    
  101.                                      }
  102.                      }
  103.              printf("Data length:%d \n",ret_data_len);
  104.              for(i=0;i<ret_data_len;i++)
  105.                      printf("%02X ",sendbuf[i]);
  106.      
  107.              printf("\n");       
  108.              printf("\n");       
  109.              printf("\n");       

  110.    ret = sendto(new_fd, sendbuf, sendbuf[1]+2, 0, (struct sockaddr *)&client_addr, cli_len);
  111.    if(ret<0)
  112.     printf("消息发送失败!错误代码是%d,错误信息是'%s'/n", errno, strerror(errno));
  113.   }
  114.   else
  115.   {
  116.     printf("received failed! error code %d ??message : %s \n",errno, strerror(errno));   
  117.   }
  118.   
  119.   /*
  120.   处理每个新连接上的数据收发结束
  121.   */
  122.   //printf("pthread exit!");
  123.   fflush(stdout);
  124.   sleep(1);
  125.   //pthread_exit(NULL);
  126.   
  127. }



  128. void initial_udp()
  129. {
  130.   /*
  131.   设置每个进程允许打开的最大文件数
  132.   */
  133.   
  134.   rt.rlim_max = rt.rlim_cur = MAXEPOLLSIZE;
  135.   if (setrlimit(RLIMIT_NOFILE, &rt) == -1)
  136.   {
  137.     perror("setrlimit error!\n");
  138.     exit(1);
  139.   }
  140.   else
  141.   {
  142.     printf("setting rlimit success! \n");
  143.   }

  144.   /*
  145.   开启 socket 监听
  146.   */
  147.   
  148.   if ((listener = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
  149.   {
  150.     perror("socket create failed!\n");
  151.     exit(1);
  152.   }
  153.   else
  154.   {

  155.     printf("Starting listening \n");
  156.   }
  157.   
  158.   /*
  159.   设置 socket属性,端口可以重用
  160.   */
  161.   
  162.   int opt=SO_REUSEADDR;
  163.   setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));


  164.   setnonblocking(listener);
  165.   bzero(&my_addr, sizeof(my_addr));
  166.   my_addr.sin_family = PF_INET;
  167.   my_addr.sin_port = htons(HOST_PORT);

  168.   my_addr.sin_addr.s_addr = inet_addr(HOST_IP_ADDRESS);

  169.   if (bind(listener, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) == -1)
  170.   {

  171.           printf("socket : %s   \n", inet_ntoa(my_addr.sin_addr));
  172.     perror("bind error! \n");
  173.     exit(1);
  174.   }
  175.   else
  176.   {
  177.     printf("IP and port bind : \n");
  178.                 printf("IP  : %s   \n", inet_ntoa(my_addr.sin_addr));
  179.     printf("port: %d \n",ntohs(my_addr.sin_port));
  180.   }
  181.        
  182.         }
  183.        
  184.        
  185.        
  186.        
  187.         void close_udp(unsigned int listen)
  188. {
  189.          close(listen);
  190.                
  191.         }


  192.        
  193. void create_epoll_events_udp(unsigned int events_fd)
  194. {

  195.   while (1)
  196.   {
  197.    /*
  198.             等待有事件发生
  199.     */
  200.    
  201.     printf("kdpfd values: %d \n",events_fd);
  202.     nfds = epoll_wait(events_fd, events, 10,-1 );
  203.     printf("nfds values: %d \n",nfds);       
  204.     if (nfds == -1)
  205.     {
  206.       perror("epoll_wait error! \n");
  207.       break;
  208.     }
  209.    
  210.     /*
  211.     处理所有事件
  212.     */
  213.    
  214.     for (n = 0; n < nfds; ++n)
  215.     {
  216.       if (events[n].data.fd == listener)
  217.       {
  218.         /*
  219.         初始化属性值,均设为默认值
  220.         */
  221.         
  222.         pthread_attr_init(&attr);
  223.         pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);


  224.         /*
  225.         设置线程为分离属性
  226.         */
  227.         
  228.         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  229.                                
  230.         if(pthread_create(&thread_udp_process,&attr,(void*)pthread_handle_message,(void*)&(events[n].data.fd)))
  231.         {
  232.            perror("pthread_creat error!");
  233.            exit(-1);
  234.         }      
  235.        }
  236.      }
  237.      //sleep(1);
  238.   }       
  239.   
  240.   close_udp(listener);

  241.         }
  242.        

  243. void udp_process()
  244. {
  245.                 kdpfd=create_epoll_udp(MAXEPOLLSIZE);
  246.   create_epoll_events_udp(kdpfd);
  247.   
  248.         }

复制代码
UDP部分,网上找的的参考代码,简单修改了一下

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP