import  threading 
import  time 
import  random 
 
 
def  do_shit( )  ->  None :
    '''Эту функцию будет вызывать другая - "сигнальная" функция''' 
    print ( f'Shit called at {time.perf_counter()-START}' ) 
    print ( f'Shit got: {random.randint(1,1000)}' )   # имитируем какую-то херню 
 
 
def  signal_loop( )  ->  None :
    '''Функция должна сигналить раз в 3 секунды, запускается в отдельном Thread''' 
    print ( f'signal_loop started at {time.perf_counter() - START}' ) 
    while  True :
        t =  threading .Thread ( target= do_shit,  daemon= True ) 
        t.run ( ) 
        time .sleep ( 3 ) 
    print ( f'signal_loop ended at {time.perf_counter() - START}' )   # по идее это не должно вызваться никогда 
 
 
def  find_prime( maxx: int )  ->  None :
    '''Занимающая CPU процедура''' 
    print ( f'find_prime started at {time.perf_counter() - START}' ) 
    primes =  [ ] 
    for  num in  range ( 3 ,  int ( maxx) +1 ,  2 ) :  # типо ищем простые числа 
        for  i in  range ( 3 ,  int ( num**0.5 ) +1 ,  2 ) :
            if  num % i ==  0 :
                break 
        else :
            primes.append ( num) 
    print ( f'find_prime ended at {time.perf_counter() - START}' ) 
 
 
def  main( )  ->  None :
    '''Отсюда вызываем 2 другие функции - сигнальную и занимающую CPU''' 
    t1 =  threading .Thread ( target= find_prime,  args= [ 1e6 ] ) 
    t2 =  threading .Thread ( target= signal_loop,  daemon= True )   # когда закончится 1й тред, эта хрень тоже должна кончиться 
    t1.start ( ) 
    t2.start ( ) 
 
 
if  __name__ ==  '__main__' :
    print ( 'Starting main thread' ) 
    START =  time .perf_counter ( )   # относительно START считаем прошедшее время 
    main( ) 
    print ( f'Main thread ended at {time.perf_counter() - START}' ) 
 
				aW1wb3J0IHRocmVhZGluZwppbXBvcnQgdGltZQppbXBvcnQgcmFuZG9tCgoKZGVmIGRvX3NoaXQoKSAtPiBOb25lOgogICAgJycn0K3RgtGDINGE0YPQvdC60YbQuNGOINCx0YPQtNC10YIg0LLRi9C30YvQstCw0YLRjCDQtNGA0YPQs9Cw0Y8gLSAi0YHQuNCz0L3QsNC70YzQvdCw0Y8iINGE0YPQvdC60YbQuNGPJycnCiAgICBwcmludChmJ1NoaXQgY2FsbGVkIGF0IHt0aW1lLnBlcmZfY291bnRlcigpLVNUQVJUfScpCiAgICBwcmludChmJ1NoaXQgZ290OiB7cmFuZG9tLnJhbmRpbnQoMSwxMDAwKX0nKSAgIyDQuNC80LjRgtC40YDRg9C10Lwg0LrQsNC60YPRji3RgtC+INGF0LXRgNC90Y4KCgpkZWYgc2lnbmFsX2xvb3AoKSAtPiBOb25lOgogICAgJycn0KTRg9C90LrRhtC40Y8g0LTQvtC70LbQvdCwINGB0LjQs9C90LDQu9C40YLRjCDRgNCw0Lcg0LIgMyDRgdC10LrRg9C90LTRiywg0LfQsNC/0YPRgdC60LDQtdGC0YHRjyDQsiDQvtGC0LTQtdC70YzQvdC+0LwgVGhyZWFkJycnCiAgICBwcmludChmJ3NpZ25hbF9sb29wIHN0YXJ0ZWQgYXQge3RpbWUucGVyZl9jb3VudGVyKCkgLSBTVEFSVH0nKQogICAgd2hpbGUgVHJ1ZToKICAgICAgICB0ID0gdGhyZWFkaW5nLlRocmVhZCh0YXJnZXQ9ZG9fc2hpdCwgZGFlbW9uPVRydWUpCiAgICAgICAgdC5ydW4oKQogICAgICAgIHRpbWUuc2xlZXAoMykKICAgIHByaW50KGYnc2lnbmFsX2xvb3AgZW5kZWQgYXQge3RpbWUucGVyZl9jb3VudGVyKCkgLSBTVEFSVH0nKSAgIyDQv9C+INC40LTQtdC1INGN0YLQviDQvdC1INC00L7Qu9C20L3QviDQstGL0LfQstCw0YLRjNGB0Y8g0L3QuNC60L7Qs9C00LAKCgpkZWYgZmluZF9wcmltZShtYXh4OiBpbnQpIC0+IE5vbmU6CiAgICAnJyfQl9Cw0L3QuNC80LDRjtGJ0LDRjyBDUFUg0L/RgNC+0YbQtdC00YPRgNCwJycnCiAgICBwcmludChmJ2ZpbmRfcHJpbWUgc3RhcnRlZCBhdCB7dGltZS5wZXJmX2NvdW50ZXIoKSAtIFNUQVJUfScpCiAgICBwcmltZXMgPSBbXQogICAgZm9yIG51bSBpbiByYW5nZSgzLCBpbnQobWF4eCkrMSwgMik6ICAjINGC0LjQv9C+INC40YnQtdC8INC/0YDQvtGB0YLRi9C1INGH0LjRgdC70LAKICAgICAgICBmb3IgaSBpbiByYW5nZSgzLCBpbnQobnVtKiowLjUpKzEsIDIpOgogICAgICAgICAgICBpZiBudW0gJSBpID09IDA6CiAgICAgICAgICAgICAgICBicmVhawogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHByaW1lcy5hcHBlbmQobnVtKQogICAgcHJpbnQoZidmaW5kX3ByaW1lIGVuZGVkIGF0IHt0aW1lLnBlcmZfY291bnRlcigpIC0gU1RBUlR9JykKCgpkZWYgbWFpbigpIC0+IE5vbmU6CiAgICAnJyfQntGC0YHRjtC00LAg0LLRi9C30YvQstCw0LXQvCAyINC00YDRg9Cz0LjQtSDRhNGD0L3QutGG0LjQuCAtINGB0LjQs9C90LDQu9GM0L3Rg9GOINC4INC30LDQvdC40LzQsNGO0YnRg9GOIENQVScnJwogICAgdDEgPSB0aHJlYWRpbmcuVGhyZWFkKHRhcmdldD1maW5kX3ByaW1lLCBhcmdzPVsxZTZdKQogICAgdDIgPSB0aHJlYWRpbmcuVGhyZWFkKHRhcmdldD1zaWduYWxfbG9vcCwgZGFlbW9uPVRydWUpICAjINC60L7Qs9C00LAg0LfQsNC60L7QvdGH0LjRgtGB0Y8gMdC5INGC0YDQtdC0LCDRjdGC0LAg0YXRgNC10L3RjCDRgtC+0LbQtSDQtNC+0LvQttC90LAg0LrQvtC90YfQuNGC0YzRgdGPCiAgICB0MS5zdGFydCgpCiAgICB0Mi5zdGFydCgpCgoKaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKICAgIHByaW50KCdTdGFydGluZyBtYWluIHRocmVhZCcpCiAgICBTVEFSVCA9IHRpbWUucGVyZl9jb3VudGVyKCkgICMg0L7RgtC90L7RgdC40YLQtdC70YzQvdC+IFNUQVJUINGB0YfQuNGC0LDQtdC8INC/0YDQvtGI0LXQtNGI0LXQtSDQstGA0LXQvNGPCiAgICBtYWluKCkKICAgIHByaW50KGYnTWFpbiB0aHJlYWQgZW5kZWQgYXQge3RpbWUucGVyZl9jb3VudGVyKCkgLSBTVEFSVH0nKQ==