ОС запускает процессы уничтожения при запуске многопоточного процесса Python - PullRequest
6 голосов
/ 27 марта 2012

Это самая странная вещь!

У меня есть многопоточное клиентское приложение, написанное на Python.Я использую многопоточность для одновременной загрузки и обработки страниц.Я бы использовал мульти-дескриптор cURL за исключением того, что узким местом является определенно процессор (а не пропускная способность) в этом приложении, поэтому более эффективно использовать пул потоков.

У меня 64-гигабайтная 16-Гб оперативная память i7.Мускулистый.Я запускаю 80 потоков во время прослушивания Pandora и троллинга Stackoverflow и BAM!Родительский процесс иногда заканчивается сообщением

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 )

А вот сутьClientThread:

class ClientThread( threading.Thread ):

  def __init__( self, queue ):
    threading.Thread.__init__( self )
    self.queue = queue

  def run( self ):
    while True:
      try:
        self.url, self.url_id = self.queue.get( )
      except:
        raise SystemExit

      html = StringIO.StringIO( )
      curl = pycurl.Curl( )
      curl.setopt( pycurl.URL, self.url )
      curl.setopt( pycurl.NOSIGNAL, True )
      curl.setopt( pycurl.WRITEFUNCTION, html.write )
      curl.close( )

      try:
        curl.perform( )
      except pycurl.error, error:
        errno, errstr = error
        print errstr

      curl.close( )

РЕДАКТИРОВАТЬ: О, верно ... забыл задать вопрос ... должно быть очевидно: почему мои процессы убиты?Это происходит на уровне ОС?Уровень ядра?Это связано с ограничением количества открытых TCP-соединений, которые я могу иметь?Это ограничение количества потоков, которые я могу запустить одновременно?Выход cat /proc/sys/kernel/threads-max равен 257841.Так что ... я не думаю, что это ...

Я думаю, что у меня это получилось ... Хорошо ... У меня вообще нет свободного места на диске.Есть ли способ создать пространство подкачки сейчас?Я использую Fedora 16. Там был WAP-обмен, затем я включил всю свою оперативную память, и она волшебным образом исчезла.Хвост /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)

Ответы [ 2 ]

7 голосов
/ 27 марта 2012

Вы активировали обработчик нехватки памяти ядра (OOM);он выбирает, какие процессы, чтобы убить в сложном образе, что пытается трудно убить, как несколько процессов, как можно сделать наибольшее влияние.Chrome, по-видимому, делает наиболее привлекательный процесс для уничтожения в соответствии с критериями, используемыми ядром.

Сводку критериев можно найти на справочной странице proc(5) в файле /proc/[pid]/oom_score:

   /proc/[pid]/oom_score (since Linux 2.6.11)
          This file displays the current score that the kernel
          gives to this process for the purpose of selecting a
          process for the OOM-killer.  A higher score means that
          the process is more likely to be selected by the OOM-
          killer.  The basis for this score is the amount of
          memory used by the process, with increases (+) or
          decreases (-) for factors including:

          * whether the process creates a lot of children using
            fork(2) (+);

          * whether the process has been running a long time, or
            has used a lot of CPU time (-);

          * whether the process has a low nice value (i.e., > 0)
            (+);

          * whether the process is privileged (-); and

          * whether the process is making direct hardware access
            (-).

          The oom_score also reflects the bit-shift adjustment
          specified by the oom_adj setting for the process.

Вы можете настроить файл oom_score для своей программы на Python, если хотите, чтобы он был уничтоженным.

Вероятно, лучшим подходом является добавление дополнительного свопа в вашу систему, чтобы попытаться оттянуть времякогда OOM-убийца вызывается.Конечно, наличие большего количества подкачки не обязательно означает, что вашей системе никогда не будет не хватать памяти - и вы можете не заботиться о том, как она справится, если есть большой объем своп-трафика - но это, по крайней мере, поможет вам преодолеть трудностипроблемы с памятью.

Если вы уже выделили все пространство, доступное для разделов подкачки, вы можете добавить файлы подкачки .Поскольку они проходят через файловую систему, для файлов подкачки накладных расходов больше, чем для разделов подкачки, но вы можете добавить их после разбиения диска, что делает его простым краткосрочным решением.Вы используете команду dd(1) для выделения файла ( не используйте seek для создания разреженного файла ), а затем используйте mkswap(8) для форматирования файла для использования подкачки, затем используйте swapon(8) длявключите этот конкретный файл.(Я думаю, что вы даже можете добавить файлы подкачки в fstab(5), чтобы сделать их автоматически доступными и при следующей перезагрузке, но я никогда не пробовал и не знаю синтаксис.)

0 голосов
/ 27 марта 2012

Вы делаете

raise SystemExit

, который фактически выходит из интерпретатора Python, а не из потока, в котором вы работаете.

...