10
|
Erik van Brakel scottrakes · 技术社区 · 16 年前 |
![]() |
1
4
我在.NET中编写代码,我不确定我编写代码的方式是由于.NET的限制和它们的API设计,还是因为这是一种标准的方式,但这是我过去做过这种事情的方式:
这使线程保持了我所认为的简单但健壮的模型。我希望找到一个比这个更简单的模型,但是我发现如果我尝试进一步减少线程模型,我会开始丢失网络流中的数据或错过连接请求。 它还帮助TDD(测试驱动开发),这样每个线程都在处理单个任务,并且更容易为其编写测试代码。拥有数百个线程会很快成为资源分配的噩梦,而拥有一个线程则会成为维护的噩梦。 在TDD环境中,保持每个逻辑任务一个线程的方式与每个任务一个方法的方式相同要简单得多,并且可以在逻辑上区分每个线程应该做什么。发现潜在问题更容易,解决问题也更容易。 |
![]() |
2
7
使用一个事件流/队列和一个线程池来保持平衡;这将更好地适应具有或多或少核心的其他计算机。 一般来说,比核心更多的活动线程将浪费时间上下文切换 如果您的游戏包含许多短动作,循环/回收事件队列将比固定数量的线程提供更好的性能。 |
![]() |
3
5
简单地回答这个问题,在当今的硬件上使用200个线程是完全错误的。 每个线程占用1 MB的内存,所以在开始做任何有用的事情之前,您需要占用200 MB的页面文件。 无论如何,将您的操作分解成可以在任何线程上安全运行的小块,但将这些操作放到队列上,并且为这些队列提供服务的工作线程数量是固定的、有限的。 更新: 浪费200兆有关系吗?在32位机器上,它占整个进程理论地址空间的10%——没有其他问题。在64位机器上, 声音 就像是理论上可以得到的东西的海洋中的一滴,但实际上它仍然是应用程序毫无意义地保留的一大块(或者更确切地说,大量相当大的块)存储,然后必须由操作系统来管理。它的作用是用大量无用的填充物包围每个客户机的有价值的信息,这会破坏位置,破坏操作系统和CPU将频繁访问的内容保存在最快的缓存层中的尝试。 无论如何,记忆的浪费只是精神错乱的一部分。除非您有200个内核(以及一个能够使用的操作系统),否则您实际上没有200个并行线程。你有(比如)8个内核,每个内核在25个线程之间疯狂切换。幼稚的您可能会认为,这样做的结果是,每个线程在一个速度慢25倍的核心上运行。但实际上比这更糟糕的是,操作系统花费更多的时间将一个线程从核心上取下,并将另一个线程放到核心上(“上下文切换”),而不是让代码运行。 看看任何著名的成功设计是如何解决这种问题的。clr的线程池(即使您没有使用它)就是一个很好的例子。首先假设每个核心只有一个线程是足够的。它允许创建更多的并行算法,但只能确保设计不当的并行算法最终能够完成。它拒绝每秒创建超过2个线程,因此它通过减慢线程贪婪算法的速度来有效地惩罚它们。 |
![]() |
4
2
你的平台是什么?如果是Windows,那么我建议直接查看异步操作和线程池(或者如果在C/C++中工作在Win32 API级别,则直接完成I/O完成端口)。 其思想是您有少量的线程来处理您的I/O,这使得您的系统能够扩展到大量并发连接,因为连接的数量和为它们提供服务的进程所使用的线程的数量之间没有关系。如预期的那样,.NET将您与详细信息隔离开来,而win32则不会。 使用异步I/O和这种类型的服务器的挑战在于,客户机请求的处理成为服务器上的状态机,数据到达触发状态更改。有时这需要一些适应,但一旦你做到了,这真的相当了不起;) 我有一些免费代码,用iOCP演示C++中的各种服务器设计。 here . 如果你正在使用UNIX或者需要跨平台,你在C++中,那么你可能想看看提供ASI/I/O功能的Boost ASIO。 |
![]() |
5
0
我认为你应该问的问题不是200作为一个普通的线程数是好是坏,而是这些线程中有多少是活动的。 如果在任何一个特定的时刻只有几个人是活跃的,而其他人都在睡觉或等待什么,那么你就没事了。在这种情况下,休眠线程不会让您付出任何代价。 但是,如果这200个线程都是活动的,那么在这200个线程之间进行线程上下文切换将浪费大量的CPU时间。 |
|
Ma Joonyoung · 粗粒度和细粒度链表的时间比较 1 年前 |
![]() |
user1700890 · 了解交互式代理Python API中的线程 2 年前 |
![]() |
AntonBoarf · 为什么要将实例变量指定给局部变量? 2 年前 |
![]() |
rhymes · 如何让线程操作相同的java列表 2 年前 |