Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 25, 2019 11:41:50

Anatolich
Зарегистрирован: 2017-10-31
Сообщения: 11
Репутация: +  0  -
Профиль   Отправить e-mail  

Завершение основного потока из дочернего.

Цель задачи использовать таймер в роле watchdog, который завершит исполнение скрипта в случае бездействия пользователя или простоя скрипта. Два мои примера ниже, не работаю как я хочу, помогите решить задачу.

Тут по exit(0) работа не завершается.

 import threading
import msvcrt
import time
stop = True
def time_th():
    global stop
    while stop:
        stop = False
        for i in range(5,0,-1):
            time.sleep(2)
            print(i)
    exit(0)
trh =  threading.Thread(target=time_th)
trh.start()
key = None
while key != b'\x1b':
    key = msvcrt.getch()
    stop = True
    print(key)

Тут после timer.run(), код вообще не отрабатывает.
 import threading
import msvcrt
import time
class time_(threading.Thread):
    def __init__(self, ):
        super(time_, self).__init__()
        self.t_worck = True
    def run(self):
        while self.t_worck:
            self.t_worck = False
            for i in range(5,0,-1):
                time.sleep(2)
                print(i)
        exit(0)
    def m_continue(self):
        self.t_worck = True
timer = time_()
timer.run()
key = None
while key != b'\x1b':
    key = msvcrt.getch()
    timer.m_continue()
    print(key)

Отредактировано Anatolich (Янв. 27, 2019 13:54:49)

Офлайн

#2 Янв. 27, 2019 13:52:06

Anatolich
Зарегистрирован: 2017-10-31
Сообщения: 11
Репутация: +  0  -
Профиль   Отправить e-mail  

Завершение основного потока из дочернего.

Господа специалисты, неужели непосильная задача для вас или для Python-а?

Офлайн

#3 Янв. 28, 2019 16:35:57

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Завершение основного потока из дочернего.

Anatolich
Два мои примера ниже, не работаю как я хочу, помогите решить задачу.
давайте по порядку, как вы хотите чтобы оно работало?
Anatolich
Тут по exit(0) работа не завершается.
а что должна? у вас же еще цикл while key != b'\x1b': крутится, и программа не завершит свою работу пока key != b'\x1b'
exit(0) вообще там не сработает ну ни в какую, он просто вызовет выход из потока. https://stackoverflow.com/questions/905189/why-does-sys-exit-not-exit-when-called-inside-a-thread-in-python
Можно его заменить на os._exit(1) но он убьет ваш скрипт напрочь и мгновенно, так что никакие “финальные” блоки(например закрытие файла если вы его открыли через менеджер контекста with) не успеют отработать. Если вас это устраивает, то это по сути единственныый способ реализовать вот это все в вашей ситуации,(под юникслайк ОС есть еще вариант через signal попробовать https://stackoverflow.com/questions/492519/timeout-on-a-function-call) иначе нужно пересматривать архитектуру. Например посмотреть в сторону asyncio.



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Офлайн

#4 Янв. 28, 2019 17:16:06

Anatolich
Зарегистрирован: 2017-10-31
Сообщения: 11
Репутация: +  0  -
Профиль   Отправить e-mail  

Завершение основного потока из дочернего.

давайте по порядку, как вы хотите чтобы оно работало?

Задача.
Есть удаленный linux сервер, на нем необходимо запускать скрипт, который имеет простое TUI меню, переход по пунктам меню осуществляется вводом номера пункта с клавиатуры(ожидаю в цикле нужные мне клавиши), если пользователь вышел из удаленной сессии или сессия завершилась по тайм-ауту, но скрипт не был завершен, он будет висеть в памяти. Задача такая, нужен некий таймер, который в случае бездействия пользователя, например 5 минут, завершит скрипт.

Отредактировано Anatolich (Янв. 28, 2019 17:16:29)

Офлайн

#5 Янв. 29, 2019 09:59:59

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Завершение основного потока из дочернего.

Anatolich ой шото вы недоговаривате, ибо я испытываю когнитивный диссонанс читая:

Anatolich
Есть удаленный linux сервер
и
Anatolich
import msvcrt
msvcrt виндовая приблуда и под линуксом работать не будет.
Если реально под линуксом то там многопоточность не нужна, можно обойтись сигналами, както так:
 #!/usr/bin/python3
# -*- coding: utf-8 -*-
import os
import signal
import time
IDLE_TIMEOUT = 10   # таймаут бездействия в секундах
CHECK_INTARVAL = 2 # интерал проверки таймаута в секундах
def handler(signum, frame):
    idle_time = time.time() - last_activity  # время простоя
    if idle_time > IDLE_TIMEOUT:   # если время простоя больше таймаута бездействия
        exit(0)
    else:                                      # иначе запустить повторно проверку через CHECK_INTARVAL секунд
        signal.alarm(CHECK_INTARVAL)
signal.signal(signal.SIGALRM, handler)
signal.alarm(CHECK_INTARVAL)
last_activity = time.time()
key = None
while key != 'b':   # тут выполняется какаято работа
    key = input('press a key')
    last_activity = time.time()
    print(key)



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Янв. 29, 2019 10:15:48)

Офлайн

#6 Янв. 29, 2019 10:06:59

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Завершение основного потока из дочернего.

Что то я не понял. Говорите сервер на линуксе, при этом используете msvcrt

msvcrt — Useful routines from the MS VC++ runtime

These functions provide access to some useful capabilities on Windows platforms.
Это не должно работать.

А вообще, можно конечно и потоки, но это всегда сложнее, чем написать просто линейный код. Вот прям сходу я могу предложить следующий очень простой вариант.
Вы пишите 2 программы. Первая это ваше TUI приложение. Оно должно как им то образом уведомлять о том что юзер активный. Судя по описанию, таким может быть факт нажатия пользователем клавиши. Пускай по нажатию клавиши будет создаваться временный файл (более продвинуто использовать unix сокеты) c именем /tmp/mytui/123, где 123 это PID процесса. А в сам файл пишется текущее время. На старте программы тоже такое надо сделать, что бы было начальное значение.
Вторая программа это тот самый watcher, в цикле раз в N времени ищется с помощью модуля glob файл в директории /tmp/mytui и считывает в них время. Если разница текущего времени с записанным более выбранного вами порога, то зная из имени файла pid процесса шлем ему сигнал о завершении и удаляем файл.
Это прям на мой взгляд одно из самых простых и доступных решений.



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#7 Янв. 29, 2019 10:08:54

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Завершение основного потока из дочернего.

PEHDOM
я сперва тоже хотел предложить ровно то, но после того как увидел о том что там используется msvcrt изменил мнение, в торону более простого. (ну как то “не уровень” у ТС, может и тот код не сам писал, а взял откуда то)



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#8 Янв. 30, 2019 10:14:56

Anatolich
Зарегистрирован: 2017-10-31
Сообщения: 11
Репутация: +  0  -
Профиль   Отправить e-mail  

Завершение основного потока из дочернего.

Господа не зацикливайтесь на msvcrt, это примеры, их я тестил на Win.
А вообще желательно решение кроссплатформенное (Возможна предстоит работа на удаленных Win серверах) и на python2.7

Отредактировано Anatolich (Янв. 30, 2019 10:57:30)

Офлайн

#9 Янв. 30, 2019 10:27:03

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Завершение основного потока из дочернего.

Anatolich
А вообще желательно решение кроссплатформенное и на python2.7
А чем не устраивают три предложеных выше решения?



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Офлайн

#10 Янв. 30, 2019 10:35:29

Anatolich
Зарегистрирован: 2017-10-31
Сообщения: 11
Репутация: +  0  -
Профиль   Отправить e-mail  

Завершение основного потока из дочернего.

А кто сказал, что не устраивает? Я до утончил задачу и пояснил использовании msvcrt.

Оно собственно и с os._exit(0) работает, пост #3.

Отредактировано Anatolich (Янв. 30, 2019 10:45:16)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version