我正在尝试使用python的多处理,多线程和原始套接字来模拟网络(仅限TCP)。
我在做什么?
- 创建一个子进程,用于嗅探网络以获取新连接。
- 子进程处理1000个连接并在生成另一个子进程(显然是通过主进程)后自行终止。这将完成相同的工作。
- 所有连接信息都存储在特定于流程的字典中。
- 每个连接,我正在创建一个Timer线程,如果连接空闲5秒钟,它将从字典中删除连接。 (而且我也会从线程返回。)
- 删除连接时,我正在取消引用该连接的计时器线程和所有其他字典参数。
- 从字典中删除最后一个元素后,我正在调用
gc.collect()
来收集垃圾并调用os._exit(0)
,以便子进程终止。 (请记住,另一个兄弟进程已经接管了。)
醇>
为什么我这么复杂?
- 每个连接都需要有自己的Timer,因为它必须在5秒不活动后死掉。
- 我尝试使用单个进程处理所有继续占用内存的连接。 (虽然我按照上面的方法,内存没有被释放。)最后,4GB内存的机器挂起使我无法使用它。 (键盘和鼠标中断非常慢。)
- 所以我只为1000个连接创建了一个子进程,然后终止它。哪个释放了内存(我已经把它看作是Python使用的内存大部分都是常量)。
- 由于我正在终止子进程,因此应删除与其关联的所有线程。 (我已经读过,除非父进程死掉,否则不会删除Python中的线程,这不是这里的情况。)
醇>
我的问题是什么?
- 我多次看到错误(每个子进程多次),
Can't start new thread.
虽然我使用os._exit()
明确终止子进程。我知道创建新线程可能存在限制。但我不认为它会像2000或3000那样太少。因为我终止子进程,所以我希望线程也被删除。 (如果我错了,请纠正我。)
- 有时,在生成新的子进程时会出现此
Can't start new thread.
错误。我无法理解为什么它在创建子进程时显示线程错误?
- 我很少见过,在第一个子进程本身开始时,上面的错误就出现了。 (毫无疑问,之前的Python实例正在几秒钟之前被杀死。)由于进程列表中没有Python的实例(在Linux中),很明显前一个实例中的所有线程都已被清除,但未反映在这种罕见的情况。
醇>
毫无疑问,我忽略了try except
的错误,很高兴知道:
- 为什么错误会带来如此少的线程?
- 关于哪些参数(OS和python),创建新线程取决于哪些?
- 如何避免上述错误? (我只有一个,它只会创建一个后台线程作为守护进程,而不是为每个连接创建一个计时器线程。除此之外,还有更好的解决方案吗?)
醇>