Chinaunix首页 | 论坛 | 博客
  • 博客访问: 68411
  • 博文数量: 30
  • 博客积分: 1260
  • 博客等级: 中尉
  • 技术积分: 285
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-03 12:27
文章分类

全部博文(30)

文章存档

2010年(30)

我的朋友

分类: C/C++

2010-07-26 11:28:21

   考虑一个问题,并发处理有几种工作方式?
 
   嵌入式开发中,我们的设备带有一个HTTP服务器,对服务内容要求能够进行并发处理.这里不讨论并发处理中的编程细节,只是描述一下并发处理所采用的工作方式.
 
1. 单进程
   当并发要求不是太高的时候,我们可以使用单进程的方式来实现,比如以下一个TCP连接处理过程:

socket()
...
bind()
...
listen(listen_fd, x)
...
conn_fd = accept()

   listen建立连接对列,accept返回时代表有一条连接已完成了三次握手,因此,可以看到,在并发处理中,对于一个listen_fd,会有多个conn_fd,每个conn_fd是一个新的连接,在此,引入POLL处理这种情况。

struct pollfd client[MAX];
int conn_fd;

client[0].fd = listen_fd;
client[0].events = POLLIN;
for(;;)
{
   poll();
   if(client[0].revents & POLLIN)
   {
       /*New client connection */
       conn_fd = accept();
       for(i = 0; i < MAX; i++)
       {
          if(client[i].fd < 0){
             client[i].fd = conn_fd;
             client[i].event = POLLIN;
          }
        }
        for(i = 1;i < MAX; i++)
        {
           if(client[i].fd < 0) continue;
           if(client[i].revents &(POLLRONORM | POLLERR))
           {
              read();
              write();
           }
       ...
}

   以上代码可以实现一个小并发的处理,但因为只有一个进程,并发能力肯定不好,但好处是,不用考虑多线程时会出现的竞争问题。
 
2. 多线程
   在Linux中,线程是基于内核线程,具有独立调度的能力,因此,线程是处理并发一个很好的方式。在上面的代码中,当检测到有新连接进入时,即创建一个线程处理后继的流程,情能会得到很大的提升。
   多线程处理时要注意的问题是对数据的保护。
 
总结:
   I/O复用中,POLL与SELECT有同样的效能,但POLL实际上还是轮循的处理方法,当并发数巨大时,性能下降的明显,在Linux2.6中,基于事件驱动的EPOLL是良好的替代方案,只是EPOLL的用法复杂一些。
 
 


阅读(661) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~