线程池的问题

bridge 2000-08-11 11:40:00
想用线程池来开发一个服务程序。
希望大家给我提提意见,我现在是一头雾水。

我的程序不打算使用MFC。好象用不了什么 消息。

做线胜池我到底要注意些什么呢?
有经验的,能不能给个程序框架啊!
...全文
310 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
softit 2000-09-25
  • 打赏
  • 举报
回复

收发数据缓冲区可以动态分配,存于一个链表中,每次有数据到达,通过Event通知解释线

程即可,不存在缓冲区不够的问题如果连接数不超过300个,都可以考虑每个客户用一个线

程来管理,这样逻辑实现最简单否则只能考虑CreateIoCompletionPort(),我在做一个大型

应用,深有体会
oldworm 2000-09-25
  • 打赏
  • 举报
回复
讨论这么激烈,我也想废话一句。
我实现了两个类,一个复杂一点,支持线程池的处理,主要是处理动态分配线程的删除问题和给线程命名。对于这个东西我用的方法很简单,在线程基类使用静态变量管理这些东西,所有线程池相关函数全部使用静态函数。
softit 2000-09-24
  • 打赏
  • 举报
回复
CreateIoCompletionPort()是个微软很不错的思想,不知道unix有没有类似的方法,不然unix如何支持几千个连接?每个线程对应一个连接当然不行,但waitformultiobject有64个事件的限制,因此每个线程最多只能服务于63个socket连接,而NT很难支持数千个线程,unix也一样,看来CreateIoCompletionPort()是唯一支持大量连接的方案
不知道超级unix机如何能做到大量的连接
xubin_sh 2000-08-15
  • 打赏
  • 举报
回复
如果只考虑Windows NT的话,那很简单
首先用CreateIoCompletionPort创建一个IOCompletionPort
然后用GetQueuedCompletionStatus/PostQueuedCompletionStatus读写数据,
但是我没用过,你可你参考《Windows高级编程》,中有很详细的描述
在unix下,我写过一个程序,我是用mutex完成的,首先,用一个mutex只让一个线程进入等待读数据的状态,当数据包没有的时候,那个线程都block在Read这个函数上,其他线程block在mutex上,当读到数据包时离开mutex,进入处理数据部分,那下一个被block在mutex的线程,取得mutex,进入等待数据状态(当然只会有一个线程)其他的线程,还是被block在mutex上,当处理完数据时,回到循环开始,继续请求那个mutex,这个是根据Windows的CreateIoCompletionPort启发写出来的。
IIS和Sql server用的就是CreateIoCompletionPort,线程池的难点是如何动态的根据请求量的大小,改变在池中的线程数量,IIS的算法,我在Microsoft上好像看到过,当然线程池的数量也要根据CPU的个数来决定
tibetty 2000-08-15
  • 打赏
  • 举报
回复
我做过一个线程池的程序,要注意的东东包括:
1.线程的代码如何编写,这取决于调度是如何做的,如果是动态创建,则无花样可言,否则要用
Event来调度,即让你的线程等待在一个事件上,线程代码本身是一个循环,调度程序通过设事件的信号状态来激活该线程。
2.线程池的调度,肯定要涉及公共数据的访问,如调度程序要根据是否空闲来判断应否激活,激活线程后要置忙标志,线程在一次循环完成后要设空闲标志等等,由于是异步进行,对这些数据的访问要使用Semaphore, CriticalSection, Mutex等信号量。

做的过程中如碰到问题,可以一起解决。

bridge 2000-08-15
  • 打赏
  • 举报
回复
xubin_sh:
你提供的这个算法很精彩,我刚才想了想,发现,每个线程可以充分利用端口。
我把它归纳了一下:
1。先初始化SOCKET(直到接收哪个环节),SOCKET为全局变量
2。接收函数,接收函数中创建一个禁区,在这个禁区内存放 rev/revfrom函数来接受包
接受的数据缓冲区来自每个线程的内部变量。
3。线程函数,函数内有一个数据区。初始化这个数据区后,调用接受函数(参数之一是
数据缓冲区的地址),

对于数据来源比较平均,稳定的SOCKET,采用这样的结构,创建合理的线程数量。无疑,在
效率和消耗资源的问题上是最佳的。
但对于数据来源很不平均的SOCKET,又有什么方法可以改进它呢?这个问题因该就是你
说的那个 动态分配线程数量的问题了。这个问题,费神费力啊!
期待大家的意见,和想法
bridge 2000-08-15
  • 打赏
  • 举报
回复


对于这个问题我还有几点想问问。
通常,建立两个线程,一个接收数据,另个处理处理处理数据。再加一些线程间的同步。
可以实现一个线程池的问题了。
(1) 其算法应该是这样:一个发屋,有两个人,A,门童(看来这个发屋比较高级),接待客人的。B,理发师。门童在门口等人,有一个客人来了,他看理发师有没有空,有,则交给理发师。没有,则一直等他空闲。然后再交给理发师,自己再到门口,等下一个顾客。---- 很显然,门童在等理发师的期间,很可能有其他顾客。

(2) 这个算法的稍微的改进一下是:在理发屋里加个板凳(这个板凳是禁区)。门童只看板凳有没有空,而不关理发师怎么样。---- 线程A收到数据,存放到公共区(禁区,只能有一个数据访问),同时发个消息给工作线。

这个算法还是不够理想,怎么呢?当然一个简单的改进是,理发屋里板凳多放几个,问题就是,
如果所有的理发师都在工作,而板凳已经满了,这是如果还要有人想来理发怎么办呢?看来只能
到其他家理发屋那里去了。(数据包丢失了)

看来这家发屋的生意真的很好,一家小的店铺已经满足不了红火的生意了。必须扩容。
这里就叫理发公司吧。理发公司看来分成三个部门比较合适。一个接待室,一个分配室,一个
工作室。接待室的座位比较少,分配室的座位比较多,接到一个顾客,先到接待室,同时告诉
分配室,分配室的人接走这个人,同时看看工作室里哪个BARBER闲着,这通知他把人接走。
这里真正意思是实现了二级缓存。想想在这样的情况下不太可能会丢包了。
不多写了,出鼻血了。
谢谢各位,帮我看看这 3 算法是否真的有效。
bridge 2000-08-15
  • 打赏
  • 举报
回复
看的出来,二位都是高手级的人物。
做线程池只是我要做的程序的第一步,第二步是要将这个程序变成一个标准的NT 服务程序。
经过对一些代码的研究,和线程同步问题的研究,我最初定下来的想法是:
采用MSG。通过消息来传递数据。
(我的程序采用的是UDP包,所以没有了创建连接的问题,取得的数据直接处理就可以了)
大溉想法是这样的。有三个类。1,类一,接收数据包,从端口上读数据,然后往数据包的POOL
中添数据,同时发给凋度类一个消息。 2。调度类,从消息循环中读取一个消息,向每个线程
发消息,同时将数据传递过去,3,工作类,处理没有数据。
这样的好处是,只要消息循环对消息队列的长度没有限制,和接受数据的缓冲池足够的大,
可以认为,接受数据的线程和工作线程是同时工作的。
我在清华的BBS上问时,有人说,采用消息方式速度没有用EVENT和信号量的方式快。
(这点我不是很清楚,同时我想问一下,WINDOWS对消息循环的长度有没有限制呢?>

我另外的方法,基本同 tibetty.
在线程函数中,我用了 WaitForSingleObject(a_event);
这个EVENT,我采用的是自动模式。因为用的是UDP数据包,对于哪个线程处理数据我并
不关心,来一个数据之后,我发一个事件,系统会让某个等待的线程激活,响应这个数据。
这么做,我省去了调用具体线程的方法。这种方式下,我用的是 CriticalSection 对一个公共
数据区的读写。
有人建议我用 semaphore,这方面的资料我见的不多,它好象是可以作到对某个资源,限制
有多少个线程读取它。我实在想不出怎么做。希望大家给我提些意见。
对 xubin_sh的资料,我十分感谢,对于这几个函数我不是很熟,但我会参考MSDN,以决定
采用什么方案的。同时希望你能不能在这里贴一些这方面的资料呢?

谢谢各位。
bridge 2000-08-14
  • 打赏
  • 举报
回复
就是NT SERVER上的一个数据包处理服务程序
xubin_sh 2000-08-14
  • 打赏
  • 举报
回复
你是要考虑unix的可移植性,还是只在Windows系统上开发?

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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