LINUX C 多线程 问题,顺序影响执行结果?

色郎中 2015-02-10 08:07:24


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

将该udp_process();函数,放在两个打印字符的线程后面执行,结果如上图,三个线程都正常工作


void main(int argc, char **argv)
{
initMutex();
initial_udp();


//udp_process();
/*
初始化属性值,均设为默认值
*/

pthread_attr_init(&attr2);
pthread_attr_setscope(&attr2, PTHREAD_SCOPE_SYSTEM);
pthread_attr_setdetachstate(&attr2, PTHREAD_CREATE_DETACHED);

if(pthread_create(&thread_loop_print,&attr2,(void*)pthread_handle_message2,NULL))
{
perror("pthread_creat error!");
exit(-1);
}

if(pthread_create(&thread_loop_print2,&attr2,(void*)pthread_handle_message3,NULL))
{
perror("pthread_creat error!");
exit(-1);
}

udp_process();

pthread_join (thread_loop_print, NULL);
pthread_join (thread_loop_print2, NULL);
pthread_join (thread_udp_process, NULL);
while(1)
{
sleep(1);
}
//return 0;

}



修改代码中,
将udp_process();函数先执行, 结果如下图:

两个打印字符串的线程,没有执行,, 只有处理UDP 数据包的 线程正确执行, UDP 使用的是EPOLL方式

顺序很有影响么?

...全文
173 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhxianbin 2015-02-11
  • 打赏
  • 举报
回复
可以用 pthread_create 去调用这个创建一个线程
色郎中 2015-02-11
  • 打赏
  • 举报
回复
网上找的的代码,简单修改了一下

#include "udp.h"


  /* 
  创建 EPOLL 句柄,
  */
 
int create_epoll_udp(unsigned int event_num)
{
	int epoll_fd;
	
	epoll_fd= epoll_create(event_num);  
  len = sizeof(struct sockaddr_in);
  ev.events = EPOLLIN | EPOLLET;
  ev.data.fd = listener;
  if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listener, &ev) < 0) 
  {
    fprintf(stderr, "epoll set insertion error: fd=%d \n", listener);
    return -1;
  }
  else
  {
    printf("socket adding in  epoll success! \n");
  }
  
	return epoll_fd;
	
	}
	

	
	
/*
 setnonblocking--设置具备为非阻塞方式
 */
int setnonblocking(int sockfd)
{
  if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1)
  {
    return -1;
  }
  return 0;
}


/*
 pthread_handle_message --线程处理 socket上的消息收发
  */
  
void* pthread_handle_message2()
{
	while(1){
		printf("this is thread 2!\n");
		fflush(stdout);
		sleep(1);
		//pthread_exit(NULL);
	}
}
void* pthread_handle_message3()
{
	while(1){
		printf("this is thread 3!\n");
		printf("\n");
		fflush(stdout);
		sleep(3);
		//pthread_exit(NULL);
	}
}

void* pthread_handle_message(int* sock_fd)
{
	int i;
	int ret_data_len;
  unsigned char recvbuf[MAXBUF + 1];
  unsigned char sendbuf[MAXBUF+1];
  int  ret;
  int  new_fd;
  struct sockaddr_in client_addr;
  socklen_t cli_len=sizeof(client_addr);
  new_fd=*sock_fd; 

  /*
  
  开始处理每个新连接上的数据收发
  */
  bzero(recvbuf, MAXBUF + 1);
  bzero(sendbuf, MAXBUF + 1);

  /*
  接收客户端的消息
  */
  
  
  ret = recvfrom(new_fd, recvbuf, MAXBUF, 0, (struct sockaddr *)&client_addr, &cli_len);
  if (ret > 0)
  	{
    	printf("socket %d recv from : %s : %d message: %s  %d bytes \n",
           new_fd, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), recvbuf, ret);
     	printf("Hex bytes: \n");
     	
     	if(recvbuf[0]==0x40)
     		{	
     			for(i=0;i<recvbuf[1]+2;i++)
     			 printf("%02X",recvbuf[i]);
     			printf("\n");	
     			printf("\n");	
     			if(recvbuf[2]==CMD_GET_VERSION)
     				{
     					ret_data_len = getVersionInfo(sendbuf);     						
     				}
     		}
     	printf("Data length:%d \n",ret_data_len);
     	for(i=0;i<ret_data_len;i++)
     		printf("%02X ",sendbuf[i]);
     
     	printf("\n");	
     	printf("\n");	
     	printf("\n");	

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



void initial_udp()
{
  /*
  设置每个进程允许打开的最大文件数
  */
  
  rt.rlim_max = rt.rlim_cur = MAXEPOLLSIZE;
  if (setrlimit(RLIMIT_NOFILE, &rt) == -1) 
  {
    perror("setrlimit error!\n");
    exit(1);
  }
  else 
  {
    printf("setting rlimit success! \n");
  }

  /*
  开启 socket 监听
  */
  
  if ((listener = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
  {
    perror("socket create failed!\n");
    exit(1);
  }
  else
  {

    printf("Starting listening \n");
  }
  
  /* 
  设置 socket属性,端口可以重用 
  */
  
  int opt=SO_REUSEADDR;
  setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));


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

  my_addr.sin_addr.s_addr = inet_addr(HOST_IP_ADDRESS);

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

  	printf("socket : %s   \n", inet_ntoa(my_addr.sin_addr));
    perror("bind error! \n");
    exit(1);
  } 
  else
  {
    printf("IP and port bind : \n");
		printf("IP  : %s   \n", inet_ntoa(my_addr.sin_addr));
    printf("port: %d \n",ntohs(my_addr.sin_port));
  } 
	
	}
	
	
	
	
	void close_udp(unsigned int listen)
{
	 close(listen);
		
	}


	
void create_epoll_events_udp(unsigned int events_fd)
{

  while (1) 
  {
   /* 
    	等待有事件发生
    */
    
    printf("kdpfd values: %d \n",events_fd);
    nfds = epoll_wait(events_fd, events, 10,-1 );
    printf("nfds values: %d \n",nfds);	
    if (nfds == -1)
    {
      perror("epoll_wait error! \n");
      break;
    }
    
    /* 
    处理所有事件 
    */
    
    for (n = 0; n < nfds; ++n)
    {
      if (events[n].data.fd == listener) 
      {
        /* 
        初始化属性值,均设为默认值
        */
        
        pthread_attr_init(&attr);
        pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);


        /* 
        设置线程为分离属性 
        */ 
        
        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
				
        if(pthread_create(&thread_udp_process,&attr,(void*)pthread_handle_message,(void*)&(events[n].data.fd)))
        {
           perror("pthread_creat error!");
           exit(-1);
        }       
       }
     }
     //sleep(1);
  }	
  
  close_udp(listener); 

	}
	

void udp_process()
{
		kdpfd=create_epoll_udp(MAXEPOLLSIZE);
  create_epoll_events_udp(kdpfd);
  
	}


色郎中 2015-02-11
  • 打赏
  • 举报
回复
引用 1 楼 zhxianbin 的回复:
现有代码看不出什么问题
主贴贴的代码是没有问题, 问题出在对网络找的代码的封装上....
void create_epoll_events_udp(unsigned int events_fd)
{
 
  while (1) 
  {
   /* 
        等待有事件发生
    */
     
    printf("kdpfd values: %d \n",events_fd);
    nfds = epoll_wait(events_fd, events, 10,-1 );
    printf("nfds values: %d \n",nfds);   
    if (nfds == -1)
    {
      perror("epoll_wait error! \n");
      break;
    }
     
    /* 
    处理所有事件 
    */
     
    for (n = 0; n < nfds; ++n)
    {
      if (events[n].data.fd == listener) 
      {
        /* 
        初始化属性值,均设为默认值
        */
         
        pthread_attr_init(&attr);
        pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
 
 
        /* 
        设置线程为分离属性 
        */ 
         
        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
                 
        if(pthread_create(&thread_udp_process,&attr,(void*)pthread_handle_message,(void*)&(events[n].data.fd)))
        {
           perror("pthread_creat error!");
           exit(-1);
        }       
       }
     }
     //sleep(1);
  }   
   
  close_udp(listener); 
 
    }
     
问题出在这个函数里,,while 循环这里,, 在main里调用 这个函数后,,相当于把 while 循环,放到了main主函数里,,因此,如果先执行这个函数后,, 只有while 里的内容被执行了,, while后的代码都得不到执行 如果把这个函数,放在最后执行,,则相当于把while放在了最后,,所以前面建立的两个线程能正常执行
zhxianbin 2015-02-10
  • 打赏
  • 举报
回复
现有代码看不出什么问题

23,222

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧