Семафор Python, похоже, не работает в Google Colab - PullRequest
0 голосов
/ 23 июня 2019

Я пытаюсь следовать этому примеру

ограничить количество потоков, работающих параллельно

Чтобы ограничить количество потоков, с которыми я работаю.

Когда я пытаюсь этот код

import threading
import time

maxthreads = 5
sema = threading.Semaphore(value=maxthreads)
threads = list()

def task(i):
    sema.acquire()
    print( "start %s" % (i,))
    time.sleep(2)
    sema.release()

for i in range(10):
    thread = threading.Thread(target=task,args=(str(i)))
    threads.append(thread)
    thread.start()

Это вывод

start 0start 1
start 3start 2


start 4

2-я половина выхода не приходит.Возможно, это как-то связано с колабом?

Если это так, есть ли рекомендуемый способ ограничения количества потоков в многопоточности colab?

Я также пробовал ограниченный мафор, тот же результат

import threading
import time

maxthreads = 5
sema = threading.BoundedSemaphore(maxthreads)
threads = list()

def task(i):
    sema.acquire()
    print( "start %s" % (i,))
    time.sleep(2)
    sema.release()

for i in range(10):
    thread = threading.Thread(target=task,args=(str(i)))
    threads.append(thread)
    thread.start()

1 Ответ

1 голос
/ 23 июня 2019

Вы ограничиваете количество потоков в правильном направлении. Кажется, проблема в том, что после того, как процесс простаивает в течение определенного времени, Google Colab останавливает его выполнение. Я не могу найти конкретную документацию, подтверждающую это, но я полагаю, что это сделано для предотвращения злоупотреблений. Ваш код должен давать правильный вывод при локальном исполнении на вашем компьютере. Обратите внимание, что произойдет, если вы используете только 2 темы в Google Colab:

import threading
import time

maxthreads = 2
sema = threading.Semaphore(value=maxthreads)
threads = list()

def task(i):
    sema.acquire()
    print( "start %s" % (i,))
    time.sleep(2)
    sema.release()

for i in range(10):
    thread = threading.Thread(target=task,args=(str(i)))
    threads.append(thread)
    thread.start()

Вы получаете следующий вывод:

start 0
start 1

Потому что перед сном процесса печатаются только эти строки. Также обратите внимание, что вы получите правильный вывод, если вы не используете time.sleep():

import threading
import time

maxthreads = 5
sema = threading.Semaphore(value=maxthreads)
threads = list()

def task(i):
    sema.acquire()
    print( "start %s" % (i,))
    sema.release()

for i in range(10):
    thread = threading.Thread(target=task,args=(str(i)))
    threads.append(thread)
    thread.start()

Я также получаю правильный результат, если перевести процесс в спящий режим на очень короткое время с помощью time.sleep(.1).


На несвязанной ноте вы, вероятно, должны изменить

thread = threading.Thread(target=task,args=(str(i)))

К

thread = threading.Thread(target=task,args=[i])

Или могут возникнуть проблемы, когда i - это двузначное число.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...