Python: Django: обработчик сигнала и основной поток - PullRequest
6 голосов
/ 20 декабря 2011

Я создаю приложение django, которое зависит от модуля python, в котором реализован обработчик сигнала SIGINT.

Если я не могу изменить модуль, от которого я зависим, как я могу обойти ошибку "сигнал работает только в основном потоке", которую я получаю, интегрируя ее в Django?

Могу ли я запустить его в главном потоке Django? Есть ли способ запретить обработчику запускать модуль в неосновных потоках?

Спасибо!

Ответы [ 4 ]

4 голосов
/ 03 января 2013

Встроенный сервер разработки Django по умолчанию включает функцию автоматической перезагрузки, которая порождает новый поток как средство перезагрузки кода. Чтобы обойти это, вы можете просто сделать следующее, хотя вы, очевидно, потеряете удобство автоматической перезагрузки:

python manage.py runserver --noreload

Вы также должны помнить об этом при выборе производственной установки. По крайней мере некоторые из опций развертывания (например, многопоточные fastcgi) обязательно выполнят ваш код вне основного потока.

1 голос
/ 22 марта 2018

Существует более чистый способ, который не нарушает вашу способность использовать потоки и процессы.

Поместите ваши звонки регистрации в manage.py:

def handleKill(signum, frame):
    print "Killing Thread."
    # Or whatever code you want here
    ForceTerminate.FORCE_TERMINATE = True 
    print threading.active_count()
    exit(0)


if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")

from django.core.management import execute_from_command_line

signal.signal(signal.SIGINT, handleKill)
signal.signal(signal.SIGTERM, handleKill)

execute_from_command_line(sys.argv)
1 голос
/ 20 января 2016

Я использую Python 3.5 и Django 1.8.5 с моим проектом, и недавно я столкнулся с похожей проблемой.Я легко могу запустить свой код xxx.py с помощью SIGNAL напрямую, но он не может быть выполнен на Django как пакет только из-за ошибки « сигнал работает только в основном потоке ».

Во-первых, runserver с --noreload --nothreading можно использовать, но он выполняет мой многопоточный код слишком медленно для меня.

Во-вторых, я обнаружил, что код в __init__.py моего пакета работалосновная нить.Но, конечно, только основной поток может перехватить этот сигнал , мой код в пакете не может его вообще перехватить.Это не может решить мою проблему, хотя, может быть, это решение для вас.

Наконец, я обнаружил, что в Python есть встроенный модуль с именем subprocess.Это означает, что вы можете запустить субреальный завершенный процесс с ним, то есть этот процесс имеет свой собственный основной поток, так что вы можете легко запустить свой код с SIGNAL здесь.Хотя я не знаю, как с ним работать, у меня это хорошо работает.PS, вы можете найти все подробности о subprocess в документации по Python.

Спасибо ~

0 голосов
/ 06 января 2012

Хотя этот вопрос не описывает ситуацию, в которой вы находитесь, вот несколько общих советов:

Сигнал отправляется только в основной поток. По этой причине обработчик сигнала должен находиться в основном потоке. С этого момента действие, которое запускает сигнал, должно быть передано другим потокам. Я обычно делаю это, используя События . Обработчик сигнала устанавливает событие, которое будут прочитаны другими потоками, а затем поймет, что действие X было запущено. Очевидно, это подразумевает, что атрибут события должен быть общим для потоков.

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