免费注册 查看新帖 |

Chinaunix

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

多线程异常 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-09-16 12:47 |只看该作者 |倒序浏览

  1.        #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4. #include <math.h>
  5. #include <string.h>
  6. #include <sys/types.h>
  7. #include <netinet/in.h>
  8. #include <sys/wait.h>
  9. #include <unistd.h>
  10. #define PI 3.1415926
  11. #define TIMER0 0
  12. #define PORT 5000                // The port which is communicate with server
  13. #define BACKLOG 10
  14. void nettran1(void* nsockfd);
  15. int main (void)
  16. {  
  17.   int sockfd,nsockfd;
  18.   int  opt;       
  19.   struct sockaddr_in addr_local;
  20.   pthread_t threadid1;       
  21.   pthread_attr_t attr;
  22.   struct sockaddr_in addr_remote;                  // New Socket file descriptor
  23.   int sin_size;                // to store struct size
  24.   sin_size = sizeof (struct sockaddr_in);
  25.   if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
  26.             {   
  27.                printf ("ERROR: Cannot obtain Socket Despcritor\n");   
  28.                exit(1);
  29.             }
  30.   
  31.            else
  32.          
  33.                   {
  34.                       printf ("OK: Obtain Socket Despcritor sucessfully\n");
  35.               }
  36.            /* Fill the local socket address struct */
  37.         addr_local.sin_family = AF_INET;        // Protocol Family
  38.             addr_local.sin_port = htons (PORT);        // Port number
  39.             addr_local.sin_addr.s_addr = INADDR_ANY;        // AutoFill local address
  40.             bzero (&(addr_local.sin_zero), 8);        // Flush the rest of struct
  41.             opt = SO_REUSEADDR;
  42.   
  43.             setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt));
  44.   
  45.     /*  Blind a special Port */
  46.             if (bind(sockfd, (struct sockaddr *) &addr_local, sizeof (struct sockaddr)) == -1)
  47.              {
  48.       
  49.               printf ("ERROR: Cannot bind Port %d\n", PORT);
  50.               exit(1);
  51.              }
  52.   
  53.              else
  54.    
  55.               {
  56.       
  57.              printf ("OK: Bind the Port %d sucessfully\n", PORT);
  58.    
  59.                }
  60.           /*  Listen remote connect/calling */
  61.             if (listen (sockfd, BACKLOG) == -1)
  62.             {
  63.             printf ("ERROR: Cannot listen Port %d\n", PORT);
  64.       
  65.             exit(1);
  66.    
  67.             }
  68.   
  69.           else
  70.    
  71.             {

  72.             printf ("OK: Listening the Port %d sucessfully\n", PORT);
  73.    
  74.             }
  75.     while(1)
  76.           {
  77.            perror("Is there any error?")     ;
  78.         /*  Wait a connection, and obtain a new socket file despriptor for single connection */
  79.             if ((nsockfd =  accept (sockfd, (struct sockaddr *) &addr_remote,&sin_size)) != -1)       
  80.                 {
  81.                       printf ("OK: Server has got connect from %s   %d\n",  inet_ntoa (addr_remote.sin_addr),nsockfd);       
  82.                  pthread_attr_init(&attr);
  83.                  pthread_attr_setstacksize(&attr,100);   
  84.                  perror("Is there any error1?")     ;
  85.                  if(pthread_create(&threadid1,&attr,(void*)(nettran1),(void*)nsockfd)!=0)
  86.                     {
  87.                      perror("Error to create thread")     ;  
  88.                      close (nsockfd);
  89.                      continue;
  90.                     }
  91.               /*  pthread_detach(threadid1,NULL); */
  92.                  pthread_join(threadid1,NULL);
  93.                   }
  94.               
  95.             }
  96.        //close (nsockfd);

  97. }

  98. void nettran1(void* nsockfd)
  99. {
  100. double value;
  101. char sdbuf[8];          
  102.   int num,i=0,sig=4;
  103.   while(1)
  104.                    {  
  105.                       perror("send0:");
  106.                       if(i++>90)     i = 0;            
  107.                       value = sin (i * PI/ 45);  
  108.                       perror("send1:");
  109.                       gcvt (value, sig, sdbuf);
  110.                       perror("send:");
  111.                       printf("value=%s   %d\n",sdbuf,(int)nsockfd);
  112.                      // SendMessage((HWND)hwnd,MSG_MYMESSAGE,0,0);
  113.                       if ((num = send ((int)nsockfd,&sdbuf, sizeof (sdbuf),0)) ==-1)
  114.                                       {   
  115.                                perror("send:");   
  116.                                close ((int)nsockfd)  ;
  117.                                pthread_exit(NULL);      
  118.                                 }
  119.                       }
  120. }         
复制代码

代码如上,多线程函数运行后,perror检测到异常:Interrupted system call。send发动不成功。

论坛徽章:
0
2 [报告]
发表于 2006-09-18 09:16 |只看该作者
这个程序问题必较多:
1. 无法接收多个客户端,因为创建的线程是joinable的,pthread_join()会阻塞,无法accept()更多的客户端。
2. 注意线程的stacksize是否足够。
3. send失败是因为有信号唤醒了了send的阻塞。不

论坛徽章:
0
3 [报告]
发表于 2006-09-18 09:22 |只看该作者
这个程序问题必较多:
1. 无法接收多个客户端,因为创建的线程是joinable的,pthread_join()会阻塞,无法accept()更多的客户端。
2. 注意线程的stacksize是否足够。
3. send失败是因为有信号唤醒了了send的阻塞。不清楚

论坛徽章:
0
4 [报告]
发表于 2006-09-18 09:28 |只看该作者
CU的回复总是失败,也不能在编辑!

3. send失败是因为有信号唤醒了了send的阻塞。不清楚是刚刚运行就

论坛徽章:
0
5 [报告]
发表于 2006-09-18 09:30 |只看该作者
第四次!

这个程序问题必较多:
1. 无法接收多个客户端,因为创建的线程是joinable的,pthread_join()会阻塞,无法accept()更多的客户端。
2. 注意线程的stacksize是否足够。
3. send失败是因为有信号唤醒了了send的阻塞。不清楚是刚刚运行就有问题,还是过一段时间才有问题。建议采用下面的方法处理:
   a). 检查errno的编号

  1. retry:
  2.               errno = 0;
  3.               if ((num = send ((int)nsockfd,&sdbuf, sizeof (sdbuf),0)) ==-1)  {   
  4.                                if(errno == EINTR)
  5.                                       goto retry;
  6.                                perror("send:");   
  7.                                close ((int)nsockfd)  ;
  8.                                pthread_exit(NULL);      
  9.                }
复制代码

          b) 或者用pthread_sigmask屏蔽不必要的信号.

总体上感觉代码应该还有很多问题,需要仔细检查。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP