当多线程python进程运行时,操作系统开始终止进程

当多线程python进程运行时,操作系统开始终止进程,python,kill,pycurl,python-multithreading,Python,Kill,Pycurl,Python Multithreading,这是最奇怪的事情 我有一个用Python编写的多线程客户端应用程序。我使用线程来同时下载和处理页面。我会使用cURL多句柄,但瓶颈肯定是这个应用程序中的处理器(而不是带宽),因此使用线程池更有效 我有一个64b i7摇摆16GB内存。强壮的。我在听Pandora和trolling Stackoverflow和BAM时启动了80个线程!父进程有时以消息结束 Killed 其他时候,一个页面(在Chrome中这是它自己的流程)会死掉。其他时候,整个浏览器崩溃 如果您想看一些代码,这里是它的要点: 以

这是最奇怪的事情

我有一个用Python编写的多线程客户端应用程序。我使用线程来同时下载和处理页面。我会使用cURL多句柄,但瓶颈肯定是这个应用程序中的处理器(而不是带宽),因此使用线程池更有效

我有一个64b i7摇摆16GB内存。强壮的。我在听Pandora和trolling Stackoverflow和BAM时启动了80个线程!父进程有时以消息结束

Killed

其他时候,一个页面(在Chrome中这是它自己的流程)会死掉。其他时候,整个浏览器崩溃

如果您想看一些代码,这里是它的要点:

以下是父进程:

def start( ):
  while True:
    for url in to_download:
      queue.put( ( url, uri_id ) )

    to_download = [ ]

    if queue.qsize( ) < BATCH_SIZE:
      to_download = get_more_urls( BATCH_SIZE )

    if threading.activeCount( ) < NUM_THREADS:
      for thread in threads:
        if not thread.isAlive( ):
          print "Respawning..."
          thread.join( )
          threads.remove( thread )
          t = ClientThread( queue )
          t.start( )
          threads.append( t )

    time.sleep( 0.5 )
编辑:哦,对了……忘了问这个问题……应该很明显:为什么我的进程会被杀死?它是在操作系统级别发生的吗?内核级?这是因为我可以拥有的开放TCP连接数量受到限制吗?这是对一次可以运行的线程数的限制吗?
cat/proc/sys/kernel/threads max的输出是
257841
。所以…我不认为是

我想我找到了…好吧…我的驱动器上根本没有交换空间。现在有没有办法创建一些交换空间?我在经营Fedora 16。有交换…然后我启用了我所有的RAM,它神奇地消失了。跟踪
/var/log/messages
我发现了这个错误:

Mar 26 19:54:03 gazelle kernel: [700140.851877] [15961]   500 15961    12455     7292   1       0             0 postgres
Mar 26 19:54:03 gazelle kernel: [700140.851880] Out of memory: Kill process 15258 (chrome) score 5 or sacrifice child
Mar 26 19:54:03 gazelle kernel: [700140.851883] Killed process 15258 (chrome) total-vm:214744kB, anon-rss:70660kB, file-rss:18956kB
Mar 26 19:54:05 gazelle dbus: [system] Activating service name='org.fedoraproject.Setroubleshootd' (using servicehelper)
你正在做一件事

raise SystemExit

它实际上退出Python解释器,而不是正在运行的线程。

您触发了内核的内存不足(OOM)处理程序;它以一种复杂的方式选择要终止的进程,努力终止尽可能少的进程以产生最大的影响。根据内核使用的标准,Chrome显然是最有可能杀掉的进程

您可以在
/proc/[pid]/oom\u score
文件下的
proc(5)
手册页中查看标准摘要:

/proc/[pid]/oom\u分数(从Linux 2.6.11开始)
该文件显示内核当前的分数
提供此过程,以便选择
OOM杀手的过程。分数越高意味着
该流程更有可能由OOM选择-
杀手。此分数的基础是
进程使用的内存,增加(+)或
减少(-)的因素包括:
*该过程是否使用
叉子(2)(+);
*进程是否已运行很长时间,或者
使用了大量CPU时间(-);
*流程是否具有较低的nice值(即>0)
(+);
*该过程是否具有特权(-);和
*进程是否正在进行直接硬件访问
(-).
oom_分数也反映了位移位调整
由进程的oom_adj设置指定。
如果希望Python程序的
oom\u score
文件被杀死,则可以调整该文件

可能更好的方法是向系统中添加更多的交换,以尝试推迟调用OOM killer的时间。当然,拥有更多的交换并不一定意味着您的系统永远不会耗尽内存——如果存在大量交换流量,您可能不关心它的处理方式——但它至少可以让您克服内存紧张的问题


如果已经为交换分区分配了所有可用空间,则可以添加交换文件。因为交换文件要经过文件系统,所以交换文件的开销比交换分区要大,但您可以在驱动器分区后添加它们,这是一个简单的短期解决方案。使用
dd(1)
命令分配文件(不要使用
seek
创建稀疏文件),然后使用
mkswap(8)
格式化文件以供交换使用,然后使用
swapon(8)
打开该特定文件。(我认为您甚至可以将交换文件添加到
fstab(5)
中,使它们在下次重新启动时自动可用,但我从未尝试过,也不知道语法。)

检查
dmesg(8)
输出以查看内核是否记录了任何信息。
dmesg(8)中的最后一个条目
与我的路由器关联的wifi适配器相关。。。好吧,这并不能解释为什么一个完全独立的进程会消亡。请参见上面的编辑。
raise SystemExit