многопоточность питон

51 views
Skip to first unread message

Grigory Antonov

unread,
Aug 9, 2015, 1:50:31 PM8/9/15
to Django russian
День добрый,
Возможно вопрос не по джанге, а больше по питону, в любом случае буду рад, если кто скажет в какую сторону копать.

Задача: Каждые 2(две) секунды выполнять задачу, которая длится 5(секунд) и чтобы ничего не блокировалось. связей между процессами нет, просто запусскать периодически автономные задачи (будет работать как демон на продакшене).

Насколько я понял из-за GIL нужно использовать multiprocessing.*

Что сделал


from multiprocessing import Process, current_process
import time
import threading
import signal

def procfunc():
# signal.signal(signal.SIGINT, signal.SIG_IGN)
print('start '+str(current_process().pid) + ' at: '+time.strftime("%a, %d %b %Y %H:%M:%S")) 
time.sleep(5)
print(str(current_process().pid)+' work at: '+time.strftime("%a, %d %b %Y %H:%M:%S"))

def f():
p = Process(target=procfunc)
p.daemon = True
p.start()
threading.Timer(2, f).start()
while True:
time.sleep(1)

if __name__ == '__main__':
p = Process(target=f)
try:
p.start()
p.join()
except KeyboardInterrupt:
print('catched ctr+c')

Вроде пашет, процессы создаются, НО при ctrl+c из консоли падает с сообщением

^Ccatched ctr+c
Process Process-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
    self.run()
  File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
  File "./mp.py", line 18, in f
    time.sleep(1)
KeyboardInterrupt



без ловли KeyboardInterrupt
^CProcess Process-1:2:
Process Process-1:1:
Traceback (most recent call last):
  File "./mp.py", line 23, in <module>
Traceback (most recent call last):
Traceback (most recent call last):
    p.join()
  File "/usr/lib/python2.7/multiprocessing/process.py", line 145, in join
  File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
  File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
    res = self._popen.wait(timeout)
  File "/usr/lib/python2.7/multiprocessing/forking.py", line 154, in wait
    return self.poll(0)
  File "/usr/lib/python2.7/multiprocessing/forking.py", line 135, in poll
    pid, sts = os.waitpid(self.pid, flag)
KeyboardInterrupt
    self.run()
  File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
  File "./mp.py", line 8, in procfunc
    self.run()
  File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
    time.sleep(5)
  File "./mp.py", line 8, in procfunc
KeyboardInterrupt
    time.sleep(5)
KeyboardInterrupt
Process Process-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
    self.run()
  File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
  File "./mp.py", line 17, in f
    time.sleep(1)
KeyboardInterrupt



Собственно вопрос: 
что нужно сделать, чтобы корректно завершить код? Как можно завершить корректно процессы?
Буду рад даже ссылкам, сам покопаюсь, просто нужно направление как это делается в питоне.
Заранее спасибо


Serge Matveenko

unread,
Aug 9, 2015, 1:53:17 PM8/9/15
to Django russian

1. sleep кушает ресурсы.
2. (шёпотом) celery же


вс, 9 авг. 2015, 20:50, Grigory Antonov <anto...@gmail.com>:
--
Вы получили это сообщение, поскольку подписаны на группу "Django russian".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес django-russia...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

Grigory Antonov

unread,
Aug 9, 2015, 3:47:38 PM8/9/15
to Django russian
))) дада, celery это отлично.
Но хотелось бы простой скрипт, чтобы не тянуть celery с redis. 
Проект не на джанге, нужно парсить страницу локалхоста и отдавать на удаленный сервис, под такое ставить celery с друзьями крутовато.


воскресенье, 9 августа 2015 г., 20:53:17 UTC+3 пользователь Serge Matveenko написал:

Serge Matveenko

unread,
Aug 9, 2015, 5:18:25 PM8/9/15
to django-...@googlegroups.com
celery - необязательно redis.
чем cron не угодил тогда?
можно воспользоваться хорошими абстракциями, типа asyncio с multiprocessing

ладно, я таки прочитал код. у вас исключение ловится только в одном процессе же, другой прибивается потому что ему сделали join(), который неявно вызывает основной процесс перед выходом, и бросили тот же KeyboardInterrupt.

ну и вообще, я бы привел код в порядок для начала, каментов понаписал по шагам, функции поназывал бы нормально, убраk бы лишнее, не смешивал бы трединговый таймер со sleep и multiprocessing-ом. вроде несколько строк, а какая-то куча странная получилась.

я бы использовал pool процессов, в основном процессе сделал бы управление временем запуска через loop, который у вас в f() почему-то, и мониторинг статуса исполнения
Reply all
Reply to author
Forward
0 new messages