Как принудительно завершить неуправляемый поток ?

Автор feron, 25.11.23, 10:51:03

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

feron

Доброго,

запускаю потоки так:

loop = asyncio.get_event_loop()
nest_asyncio.apply(loop)
loop.create_task(func1())
loop.create_task(func2())

func2 получила результат и необходимо завершить работу неуправляемой функции func1. Как это сделать правильно?

Валерий Изранов

Цитата: feron от 25.11.23, 10:51:03необходимо завершить работу неуправляемой функции func1
Любая функция автоматически завершает работу, когда выполнилось все,что в ней написано.

feron

Цитата: Валерий Изранов от 25.11.23, 10:58:26Любая функция автоматически завершает работу, когда выполнилось все,что в ней написано.

Но не в этом случае.. в ней реализована функция которая работает со сторонним компонентом а в нем не предусмотрено неожиданное завершение работы.. а ждать пока она отработает нет не какого смысла кроме той что она первее закончит работу функции func2.


Валерий Изранов

Тогда вопрос должен звучать по другому и конкретно.

feron

#4
Цитата: Валерий Изранов от 25.11.23, 11:31:43Тогда вопрос должен звучать по другому и конкретно.

куда уж конкретней?

вот две функции:

async def func1():
    #здесь работает функция стороннего компонента
    print('start')
    await asyncio.sleep(5)
    print('end')
    return ('func1')

async def func2():
    #здесь работает функция стороннего компонента
    print('this')
    return ('func2')

Как пример, не каких флагов там не получится поставить..

Nipal

Сильно простенько Вы хотите сделать, работайте на WinApi.
Thread.png
+ Благодарностей: 1

feron

я пошел чуть другим способом.. с сохранением прогресса
import time
import multiprocessing

def func1(result):
 
    while True:
        with result.get_lock():
            # result.acquire()
            result.value += 1
            # result.release()
       
        time.sleep(0.5)
        print('printing: ' + str(result.value), flush=True)

def func2():
    print('this')
    return ('func2')

if __name__ == '__main__':
    result = multiprocessing.Value('i', 0)

    process1 = multiprocessing.Process(target=func1, args=(result,))
    process2 = multiprocessing.Process(target=func2)
   
    process1.start()
    process2.start()
   
    time.sleep(2)
    process1.terminate()

    print(str(result.value))
   
    process1.join()
    process2.join()

Nipal

Тоже правильный вариант, создали процесс и контролируете его.

feron

Есть еще предположение, при создании дочернего потока средством:

th1 = threading.Thread(target=func11)
th1.daemon=True
th1.start()

то по завершению этого основного потока придет и принудительное завершение дочернего.
но что то не выходит..

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

feron

Радость длилась не долго..

import time
import multiprocessing
import asyncio
import nest_asyncio

# result_lock = multiprocessing.Lock()

async def func1(result):
    print('starting: ' + str(result.value), flush=True)
    while True:
        with result.get_lock():
            # result.acquire()
            result.value += 1
            # result.release()
       
        await asyncio.sleep(0.5)
        # time.sleep(0.5)
        print('printing: ' + str(result.value), flush=True)

async def func2():
    print('this')
    return ('func2')

def func11(result):
    loop11 = asyncio.get_event_loop()
    nest_asyncio.apply(loop11)
    # loop11.create_task(func1(result))
    loop11.run_until_complete(func1(result))
    loop11.stop()

def func22():
    loop22 = asyncio.get_event_loop()
    nest_asyncio.apply(loop22)
    #loop22.create_task(func2())
    loop22.run_until_complete(func2())
    loop22.stop()


if __name__ == '__main__':
    result = multiprocessing.Value('i', 0)

    process1 = multiprocessing.Process(target=func11, args=(result,))
    process2 = multiprocessing.Process(target=func22)
   
    process1.start()
    process2.start()
   
    time.sleep(2)
    process1.terminate()
   
    # with result_lock:
    print(str(result.value))
   
    process1.join()
    process2.join()


Функции func1 и func2 должны работать асинхронно между собой, а не последовательно..

Вывод:
4

this
starting: 0
printing: 1
printing: 2
printing: 3

Как быть?

Nipal

Цитата: feron от 25.11.23, 14:40:12Как быть?
Это всё очень примитивно, вникать в процессы, язык я понимаю Питон?


Nipal

Я на нём не программирую и могу ошибаться, но это не тот язык для тех глобальных целей, которые Вы хотите решить.

feron

Цитата: Nipal от 25.11.23, 14:52:46но это не тот язык для тех глобальных целей, которые Вы хотите решить.

нее с таким подходом кашу не сварить..

сначала на простом и удобном языке собрать и уж потом писать на плюсах.

Nipal

Так, собирайте, только потом кашу, подогревать или переваривать не ставьте.

feron

#15
Цитата: Nipal от 25.11.23, 15:31:03только потом кашу, подогревать или переваривать не ставьте.

Не вижу в этом не каких проблем.. сама задача сформирована осталось иноязычно реализовать.. Главное это изначальная возможность реализации..

Вы опять от темы уходите..

Этот способ крайне не рекомендуемый - последствия для самой для программы могут быть непредсказуемыми..
Цитата: Nipal от 25.11.23, 13:21:42Сильно простенько Вы хотите сделать, работайте на WinApi.
Thread.png

Nipal

Вы считаете, что всё одной строкой делается?
Хотя, это уже не важно.

feron

#17
Цитата: Nipal от 25.11.23, 16:07:00Вы считаете, что всё одной строкой делается?

Хех тут скилл нужен.. нельзя так просто войти дважды в одну реку..

feron

Цитата: feron от 25.11.23, 14:40:12Функции func1 и func2 должны работать асинхронно между собой, а не последовательно..

Все правильно просто очередь вывода на ide как то по странному реализовано или непонятно.. в любом случае функции работают асинхронно..