Кажется, что IDLE (часть стандартной установки Python для Windows) не будет правильно выполнять многопоточные программы без неприятных зависаний или аварийных сбоев. Кто-нибудь знает способ исправить это?

Следующая программа всегда зависает в IDLE, но завершается нормально, когда выполняется непосредственно с интерпретатором Python:

import threading, time

printLock = threading.Lock()

def pl(s):
  printLock.acquire()
  print s
  printLock.release()

class myThread( threading.Thread ):
  def run(self):
    i = 0
    for i in range(0,30):
      pl(i)
      time.sleep(0.1)

t = myThread()
t.start()

while threading.activeCount() > 1:
  time.sleep(1)
  pl( time.time() )

print "all done!"

Образец вывода:

U:\dev\py\multithreadtest>python mt.py
0
1
2
3
4
5
6
7
8
9
1277935368.84
10
11
12
13
14
15
16
17
18
19
1277935369.84
20
21
22
23
24
25
26
27
28
29
1277935370.84
1277935371.84
all done!

Вывод при использовании IDLE Функция «Run Module» всегда зависает бесконечно примерно в то время, когда на моей машине показывается строка 23 или 24.

7
Mike Simpson 1 Июл 2010 в 02:10

3 ответа

Лучший ответ

AFAIK это дрянь, когда запускается многопоточный код в IDLE. IDLE использует GIL свободно, поэтому условия гонки и взаимоблокировки являются общими. К сожалению, я недостаточно хорошо разбираюсь в потоках, чтобы понять, как сделать этот поток безопасным, помимо очевидного.

0
Noctis Skytower 24 Авг 2016 в 14:08
import threading
print(threading.activeCount())

Печатает 1 при запуске из командной строки, 2 при запуске из режима ожидания. Так твоя петля

while threading.activeCount() > 1:
  time.sleep(1)
  pl( time.time() )

Будет завершаться в консоли, но продолжаться вечно в режиме ожидания.

Чтобы исправить проблему в размещенном коде, добавьте что-то вроде

initial_threads = threading.activeCount()

После импорта и измените заголовок цикла на

while threading.activeCount() > initial_threads:

С этим изменением код проходит 30 циклов и останавливается с «все сделано!». Я добавил это в свой список консольных Python по сравнению с простоями различий, которые должны быть задокументированы.

2
Terry Jan Reedy 29 Мар 2015 в 23:00

У IDLE есть некоторые известные проблемы, когда дело доходит до потоков. Я не знаю подавляющего количества о деталях почему это проблема, потому что я очень стараюсь держаться подальше от IDLE, но я знаю, что это так. Я настоятельно рекомендую вам просто взять IronPython и Python Tools для Visual Studio. Инструменты отладки VS абсолютно не имеют себе равных, особенно учитывая огромную библиотеку дополнений.

0
Phillip Schmidt 23 Авг 2012 в 15:58