Chinaunix首页 | 论坛 | 博客
  • 博客访问: 657466
  • 博文数量: 151
  • 博客积分: 3498
  • 博客等级: 中校
  • 技术积分: 1570
  • 用 户 组: 普通用户
  • 注册时间: 2005-02-28 18:10
文章分类

全部博文(151)

文章存档

2014年(12)

2013年(17)

2012年(17)

2011年(5)

2010年(12)

2009年(2)

2007年(26)

2006年(22)

2005年(38)

分类: WINDOWS

2007-07-08 12:00:12

分析CODEPORJECT上的使用线程池的程序
1."A ThreadPool implementation",该程序有比较好的文档.
 地址:

2."Improve your server with Thread Pooling",比较简单的实现
地址:

3."Work Queue",有实用价值的POOL
地址:


1."A ThreadPool implementation",该程序有比较好的文档.
1.1复杂,使用了很多的类
  Pool
  RequestWrapper
  ThreadRequestBase
  ThreadRequestFunction
  ThreadRequestMethod
  ClientTest
1.2有类之间的结构图

Structure


1.3有比较完整的功能和结构说明
1.4有STL的很多应用,使用了很多的技术点
   比如有CALLBACK函数;
   有指针函数;
   有类函数重载;
   有类的函数指针使用.

  缺点
1.5 线程池没有对REQUEST的管理.
1.6 线程池没有实现真正的线程池的功能,它只是使用了复杂的技术对有很多请求的情况,
   给每一个请求都分配了一个线程执行.
1.7 这样一段代码
  
DWORD WINAPI RunMainThread(LPVOID ptr)
{
    Pool *_this = static_cast(ptr);

    while(true)
    {
        while(_this->ChangeNumRunningThread(0) < _this->m_Max)
        {
            RequestWrapper *wr = _this->Dequeue();
            if(wr != NULL)
            {
                HANDLE h = CreateThread(NULL,
                            0,
                            ThreadProc,
                            wr,
                            0,
                            NULL
                            );
                if(h != NULL)
                {
                    _this->ChangeNumRunningThread(1);
                }
            }
            else if(wr == NULL) // the queue is empty, waits for a new requests
            {
                WaitForSingleObject(_this->m_EventRequestAdded, INFINITE);
            }
        }

        // waits until some request will end
        WaitForSingleObject(_this->m_EventRequestFinish, INFINITE);
    }

    return 0;
}

1)第一次进入循环如果队列中没有MAX的REQUEST,那么势必阻塞在这里
  WaitForSingleObject(_this->m_EventRequestAdded, INFINITE);
  那么后面的
  WaitForSingleObject(_this->m_EventRequestFinish, INFINITE);
  这个等待显得没有意义.
2)该循环没有退出点,因为这是一个线程中的函数,所以很不好.


2."Improve your server with Thread Pooling",比较简单的实现
2.1类个数
   CThreadLocker
   CThreadPool
   JOB
2.2结构图
  非常简单
  POOL中有一个JOB数组,两个线程从该JOB数组取出JOB并且执行.执行一个JOB也就是执行JOB中的METHOD,因为该METHOD是一个CALLBACK.所以,不同的JOB可以使用不同的函数执行.
   作者在下面说,可以把15个JOB当成15个TCP的SOCKET连接,分别与客户端通信.
   The project is well documented and it contains a simple demonstration. The demonstration displays a pool of two threads and fifteen jobs. You can think of it as fifteen connections if it was a socket server.
   对于JOB是可以添加和删除的!

3."Work Queue",有实用价值的POOL
3.1类的个数
   WorkItemBase
   CWorkQueue
3.2结构图
    CWorkQueue聚合WorkItemBase,
    CWorkQueue负责创建线程,和管理线程.
    CWorkQueue负责执行具体的WORKITEM
 3.3技术点
    有一个非常好的LISTCTRL类,可以使用CHECKBOX,COMBO BOX,PROGRESS BAR,EDIT 等等.
文件:WQDemo.rar
大小:90KB
下载:下载
3.4上面的代码是我经过修改的SERVER端使用了线程池的代码,服务线程等待TCP连接,并且接收到一个新的TCP连接后,就把该CONNECT作为一个JOB,添加到WORK QUEUE中,然后其中一个线程就会从QUEUE找一个JOB执行.
3.5CLIENT端连接可以创建大量的连接,也可以关闭连接.还可以发送信息,查看服务端的消息输出.在代码中,其中一个是VC6的CLIENT PROJECT 代码.
3.6对公共资源访问时,要使用锁,因为不同线程可能会同时对该资源写,这样就会产生冲突。读时也要加锁,如果不加锁,则一个线程对该资源读时,另外一个线程却在写,则也会产生混乱。



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